Laravel FirstOrCreate和Save()重复输入

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Laravel FirstOrCreate和Save()重复输入相关的知识,希望对你有一定的参考价值。

我有一张这样的桌子

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()只应插入新记录(如果它尚不存在)。

答案

我也遇到了同样的问题...我用一个与此处有点不同的方法来解决它:qazxsw poi

我简要解释了为什么这种方法。我不喜欢常见的数据库锁定用于很少发生的事件,由于firstOrCreate有问题,我们在繁忙的服务器上每两天就有一个例外。为了这样一个罕见的事件,在每次创建时锁定并删除一个锁......好吧...这种方法在发生时要小心,因为我是偏执的,我需要多次双重护理,就是这样。

https://gist.github.com/troatie/def0fba42fcfb70f873b7f033fbe255f
另一答案
<?php

namespace AppTraits;

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;
    }
}

$table->increments('id');
$table->integer('user_id');

你的$table->unique(array('user_id', 'DateTimeCode')); 是独一无二的,但没有递增。每次尝试创建用户时都会使用相同的user_id - 这是不可能的。

以上是关于Laravel FirstOrCreate和Save()重复输入的主要内容,如果未能解决你的问题,请参考以下文章

Laravel Eloquent - 关系上的 firstOrCreate()

laravel中firstOrCreate的使用

在 Laravel 中,有没有办法找出是不是创建了 `firstOrCreate` 或者是不是找到了行?

Laravel 8 - firstOrCreate() 不返回数据库中设置的默认值

Laravel 5 firstOrCreate 保持创建甚至设置唯一的字段

Laravel firstOrNew 与 firstOrCreate 的区别