我有一个名为 spot
和 reservation
的表。 spot
包含列 spot_id
和 spot_status
。对于预订过程,我启动一个事务,然后使用此查询获取特定行的锁定。我正在使用 php 和 mysql。
//start transaction
SELECT * FROM spot WHERE spot_id = $id FOR UPDATE ;
//if this query is successful then
1. set spot status to 1
2. insert corresponding values in reservation table.
and then commit else rollback
//transactions ends
假设有 2 个并发事务 T1 和 T2 试图保留相同的位置。根据我从本网站其他人的问题和答案中了解到的情况,如果事务不是并发的,则不会有任何问题,但在并发操作中,处理器可以随时从 T1 时间表更改为 T2 时间表。 T1 获取行上的锁后,假设处理器切换到事务 T2。然后,T2 尝试获取同一行上的锁,但它不能,因为它已被 T1 锁定。
我的问题是理论上的:
- mysql什么时候解除锁?或者有什么明确的方法 自己解锁?
- 由于T2事务无法锁定第一个查询的行,所以它会回滚吗?或者处理器让 T2 等待,直到它可以锁定该行?
- 这个问题发生死锁的可能性有多大?
最佳答案
您的锁管理策略是正确的。
如果T1首先获得了spot/spot_id=$id上的锁,那么T2将等待直到T1提交或回滚事务。如果 T1 崩溃或超时,回滚将是隐式的。
如果你想要死锁,试试这个。
让 T1 锁定第 1 行(“ fork ”),然后锁定第 2 行(“刀”)。 让 T2 锁定第 2 行(“刀”),然后锁定第 1 行(“ fork ”)。
同时运行它们。最终你会发现T2只拿着一把刀,而T1只拿着一把 fork 。他们会互相盯着对方,饥肠辘辘,等待对方放下工具。
关于php - Mysql - 并发事务中的行级锁定死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25202406/