我们正在像这样使用lockForUpdate:
DB::beginTransaction();
try {
$balance = UserBalance::where('user_id', 2)
->lockForUpdate()
->first();
$balance->usd += 100;
$balance->save();
// A LOT MORE LOGIC HERE
$balance = UserBalance::where('user_id', 7)
->lockForUpdate()
->first();
$balance->usd -= 100;
$balance->save();
} catch (\Exception $e) {
DB::rollback();
return json_encode ([
'success' => false,
'message' => 'error',
]);
}
DB::commit();
一切正常,我在提交之前尝试了一些“ sleep(20)”,并发送了另一个请购单(没有睡眠),并且该行确实被锁定,但是我们面临一个问题。当我们从cron多次运行此函数时,函数似乎在完全相同的毫秒上运行,那么锁似乎不起作用,这可能吗?还有其他解决方案而不是使用队列吗?
CRON只是多次调用路由,如下所示:
* * * * * curl http://test.com.br/test
* * * * * curl http://test.com.br/test
* * * * * curl http://test.com.br/test
答案 0 :(得分:0)
我不明白为什么这里需要使用DB::transcation
,因为此操作是原子操作。
您只需执行UserBalance::where('user_id', 2)->increment('usd', 100)
。
这会将单个查询发送到后端,将usd
的值增加100。