【发布时间】:2015-04-03 05:35:37
【问题描述】:
我们有各种表格来表示各种类型的数据。每个表都有一个相应的修订表来跟踪此数据的历史记录。每个修订(修订表中的条目)都有一个唯一编号。此编号存储在更改元数据表中。这些表中的每一个都引用了一个 parent_id。在对表进行任何更改之前,我们使用 SELECT ... FOR UPDATE 锁定父行。
在进行更新/插入后,我们还会增加更改编号并将该编号写入更改元数据表。为此,我们对更改元数据编号执行 SELECT MAX,然后将其递增。
我们看到的问题是,事务不知何故从 select max 语句中获取了旧的更改编号。举例说明:
交易1:
开始交易
用 FOR UPDATE 锁定
做事...
获取最新更改编号 (9)
插入编号为 10 的修订
提交
事务 2:
开始交易
用 FOR UPDATE 锁定
做事...
获取最新更改编号 (7)
插入编号为 8 的修订
提交
这会导致事务 2 的修订插入失败,因为更改号是唯一键。我倾向于它是一个可重复读取的问题,但我不确定旧数据如何以这种方式在事务中持续存在。对于每个事务,都有一个 START TRANSACTION 语句,然后父 ID 立即被 FOR UPDATE 锁定。我们有一个具有多个并发事务的高流量站点。任何时候都可能有很多人在等待锁。我很乐意澄清任何一点,并感谢任何人提供的任何见解。
【问题讨论】:
标签: mysql database transactions locking innodb