Laravel lockForUpdate +交易

时间:2019-03-21 13:57:39

标签: mysql laravel laravel-5 transactions pessimistic-locking

我们正在像这样使用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

1 个答案:

答案 0 :(得分:0)

我不明白为什么这里需要使用DB::transcation,因为此操作是原子操作。

您只需执行UserBalance::where('user_id', 2)->increment('usd', 100)

这会将单个查询发送到后端,将usd的值增加100。