【发布时间】:2021-02-23 21:46:47
【问题描述】:
在我的 Laravel 应用程序中有一个类,它遍历一组用户并在 transaction 中更新他们,但没有 lock。
代码大致如下:
DB::transaction(function () {
// ...
foreach($groupOfUsers as $user){
Car::where('user_id','=', $user->id)->update(['color' => 'red');
}
})
现在我使用了Paratest,它为上述类的集成测试运行多个进程。所有进程都使用相同的数据库。 每次,我对上述课程的一项测试都会失败并出现死锁。但我不明白这怎么可能。我认为只有在我实际锁定行以进行更新或使用共享锁时才会发生死锁。
如何创建只包含更新的死锁?
【问题讨论】:
-
即使使用事务也可能在写入过程中,使用多进程时,同一行将被不同进程同时使用,而该行正在被第三进程处理,另外两个将互相等待并发生死锁。
-
@Akam 你是说如果我有一个网站只在一个请求上使用
UPDATE name="bob" WHERE id=1,那么如果发生太多并发请求,这会造成死锁? -
在实际情况下不会出现这种情况,为什么一行或几行会同时更新多次? MySQl 建议尽量减少每个事务中的行数,以便将这些行释放给其他进程。
标签: php laravel transactions