【问题标题】:Laravel FirstOrCreate and Save() duplicate entryLaravel FirstOrCreate 和 Save() 重复条目
【发布时间】:2014-07-02 21:26:46
【问题描述】:

我有一张这样的桌子

Schema::create('user', function(Blueprint $table)
        {
            $table->increments('id');
            $table->datetime('DateTimeCode');
            $table->integer('user_id');
            $table->integer('Foo');
            $table->softDeletes();
            $table->timestamps();

            $table->unique(array('user_id', 'DateTimeCode'));
        });

当我尝试时

User::firstOrCreate($SomeData);

或者

$new_user = new User($SomeData);
$new_user->save();

我明白了

Integrity constraint violation: 1062 Duplicate entry

我不明白,因为我认为我的唯一值定义明确,save()firstOrCreate() 应该只在新记录不存在的情况下插入它。

【问题讨论】:

标签: php laravel-4 eloquent on-duplicate-key


【解决方案1】:
$table->increments('id');
$table->integer('user_id');

$table->unique(array('user_id', 'DateTimeCode'));

您的user_id 是唯一的,不会递增。每次您尝试创建用户时,都会使用相同的 user_id - 这是不可能的。

【讨论】:

  • 我称它为 user_id,但它可以是我不想增加但我仍然希望与 DateTimeCode 结合使用的任何字段。另外,我在问题中陈述的 Laravel 方法不应该创建新记录(如果它已经存在)。
  • 这没有任何意义。当user_id 与数据库中的记录相同时,它应该简单地执行first 部分而不是create 部分。
【解决方案2】:

我也遇到了同样的问题......我用一种稍微不同的方法解决了它,然后从这里开始: https://gist.github.com/troatie/def0fba42fcfb70f873b7f033fbe255f

我简要解释一下为什么要采用这种方法。对于很少发生的事件,我不喜欢常规的数据库锁,由于 firstOrCreate 有问题,我们每两天在繁忙的服务器上出现一次异常。为这样一个罕见的事件在每次创建时创建一个锁定并删除一个锁定......嗯......这种方法在它发生时会很小心,因为我很偏执,所以我需要加倍小心,仅此而已。

<?php

namespace App\Traits;

use Exception;

/**
 * Trait OrCreateTrait
 */
trait OrCreateTrait
{
    /**
     * @param array $attributes
     * @param array $values
     *
     * @return mixed
     */
    public static function updateOrCreate(array $attributes, array $values = [])
    {
        return static::tryManyTimes(function () use ($attributes, $values) {
            return (new static)->newQuery()->updateOrCreate($attributes, $values);
        });
    }

    /**
     * @param array $attributes
     * @param array $values
     *
     * @return mixed
     */
    public static function firstOrCreate(array $attributes, array $values = [])
    {
        return static::tryManyTimes(function () use ($attributes, $values) {
            return (new static)->newQuery()->firstOrCreate($attributes, $values);
        });
    }

    /**
     * @param callable $callback
     *
     * @return mixed
     */
    private static function tryManyTimes(callable $callback)
    {
        try {
            $output = $callback();
        } catch (Exception $e) {
            try {
                $output = $callback();
            } catch (Exception $e) {
                usleep(10000);
                try {
                    $output = $callback();
                } catch (Exception $e) {
                    usleep(100000);
                    try {
                        $output = $callback();
                    } catch (Exception $e) {
                        usleep(250000);
                        try {
                            $output = $callback();
                        } catch (Exception $e) {
                            $output = null;
                        }
                    }
                }
            }
        }
        return $output;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-28
    • 2020-06-21
    • 2018-11-28
    • 1970-01-01
    • 2019-08-08
    • 2020-04-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多