场景
拼团功能,当 A 客户开团之后(两人团),如果 B 和 C 同时支付,如何规避两人同时将拼团人数增加。
Laravel 中 sharedLock 与 lockForUpdate 的区别
sharedLock 对应的是 LOCK IN SHARE MODE
lockForUpdate 对应的是 FOR UPDATE
sharedLock 与 lockForUpdate 相同的地方是,都能避免同一行数据被其他 transaction 进行 update。
不同的地方是:
sharedLock 不会阻止其他 transaction 读取同一行
lockForUpdate 会阻止其他 transaction 读取同一行 (需要特别注意的是,普通的非锁定读取读取依然可以读取到该行,只有 sharedLock 和 lockForUpdate 的读取会被阻止。)
即 sharedLock locks only for write, lockForUpdate also prevents them from being selected
这样做是有意义的,例如,两个 transaction 要更新同一个计数器,如果不使用 lockForUpdate, 会导致两个 transaction 同时读到同一个初始值,然后在应用层逻辑中增加计数之后,提交到数据库中,后者的操作会覆盖掉前者的操作。
下面进行实操测试:
情况一:
A: lockForUpdate
B: lockForUpdate 或 ShareLock 都需要等待 A 提交事务。
未提交事务前 B 等待 A commit 后,才进行查询 B 采用 shareLock 查询也是一样效果 B 等待太久可能会超时情况二:
A: 采用 shareLock;
B:采用 LockForUpdate;
B 也必须等待 A 提交事务后,才进行查询;
B 也必须等待 A 提交事务后,才进行查询情况三:
A:采用 shareLock;
B:采用 shareLock;
B 不需要等待 A 提交,即可查出结果
B 不需要等待 A 提交,即可查出结果情况三:
A: lockForUpdate;
B: 进行更新操作,必须等待 A commit;
进行更新操作,必须等待 A commit;情况四:
A: shareLock;
B: 进行更新操作,必须等待 A commit;
A 未 commit 前 A commit 后结论:
更新操作:无论进行 shareLock 还是 LockForUpdate 其他 transaction 必须等待事务的提交才可以进行下去。
查询操作:LockForUpdate 可以屏蔽其他 transaction 对记录的查询;shareLock 可以共享查询。
网友评论