Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/237.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php Laravel队列是否防止并发请求插入重复记录?_Php_Laravel - Fatal编程技术网

Php Laravel队列是否防止并发请求插入重复记录?

Php Laravel队列是否防止并发请求插入重复记录?,php,laravel,Php,Laravel,我们有一个带有MariaDB数据库的laravelapi,在这个数据库中,我们遇到了由并发请求创建的重复记录的问题 我们假设实现一个队列可以通过一次处理一个请求来解决这个问题。 但我们仍然有相同的问题,重复记录 在应用程序中,我们有一个查找重复项的检查,但是对于同时创建相同记录的并发请求,这当然不起作用 我们无法在数据库级别使用唯一约束,部分原因是Laravel的软删除机制,部分原因是复杂的业务逻辑,如果其中一个字段的值与某一组值匹配,则应该允许重复 我们使用Redis作为队列驱动程序 我们认为

我们有一个带有MariaDB数据库的laravelapi,在这个数据库中,我们遇到了由并发请求创建的重复记录的问题

我们假设实现一个队列可以通过一次处理一个请求来解决这个问题。 但我们仍然有相同的问题,重复记录

在应用程序中,我们有一个查找重复项的检查,但是对于同时创建相同记录的并发请求,这当然不起作用

我们无法在数据库级别使用唯一约束,部分原因是Laravel的软删除机制,部分原因是复杂的业务逻辑,如果其中一个字段的值与某一组值匹配,则应该允许重复

我们使用Redis作为队列驱动程序

我们认为队列应该防止这些问题,这是错误的吗? 还是我们在实现队列的某个地方犯了错误

这是控制器的简化版本:

class CreateRecordJob extends Job implements SelfHandling
{

    public function __construct(array $data)
    {
        $this->data = $data;
    }

    public function handle()
    {
        $data = $this->data;

        // check if we have this record in the database already
        if(!$this->hasDuplicate($data)) {
            $this->createRecord();
        }
    }
}
在config/queue.php中,我们将Redis设置为默认队列驱动程序:

'default' => env('QUEUE_DRIVER', 'redis'),
在config/queue.php中,我们为redis连接提供了以下内容:

'redis' => [
    'driver'     => 'redis',
    'connection' => 'default',
    'queue'      => 'default',
    'expire'     => 60,
],
基本上-不是
您可能会发现FIFO兼容队列驱动程序的实现
laravel有接口Illumb\Console\Scheduling\Mutex为此,byt yuo需要扩展queueManager才能使用它

队列不会阻止创建具有相同数据的两个作业。看起来
hasdeplicate
函数不能正常工作。我的建议是:1。检查
hasdeplicate
是否正常工作。2.通过在
handle()
方法的第一行中添加
\DB::beginTransaction()
并在最后一行中添加
\DB::commit()
来执行检查并作为事务注入。3.对数据库中的一个或多个字段建立唯一索引。这在很大程度上取决于您的逻辑。并发请求上的db事务可能是deadlocks@michail1982仅当应用不正确时。简单的“检查是否存在,如果不存在,则插入”是事务保持一致性的完美案例。否则,您可以在另一个进程刚刚创建记录时检查该记录是否不存在。如果它不存在,1号进程将创建它,如果请求稍后出现,则创建一个副本。hasdeplicate可以正常工作。唯一索引不是当前业务逻辑的选项@ChrisCynarski这只涉及到一个表,在这种情况下,一个事务能帮我吗?@sunomad你一定要试试。这是一个完美的交易案例。如果你有一个工人,那么不管怎样,工作都会一个接一个地运行。如果后续作业中的数据相同,则这将没有帮助。如果工作正常,我会查看
hasdeplicate
方法,或者首先查看重复数据的原因。您可以启动任意数量的工作进程,但互斥在1台服务器上工作=(amazon sqs有“消息重复数据消除ID”,这可能会有所帮助