gpt4 book ai didi

具有 innodb 和可序列化事务的 Mysql 不会(总是)锁定行

转载 作者:行者123 更新时间:2023-11-29 00:58:57 28 4
gpt4 key购买 nike

我有一个带有 SELECT 和可能的 INSERT 的交易。出于并发原因,我将 FOR UPDATE 添加到 SELECT。为了防止幻像行,我使用了 SERIALIZABLE 事务隔离级别。当表中有任何行时,这一切都可以正常工作,但如果表为空则不行。当表为空时,SELECT FOR UPDATE 不会执行任何(独占)锁定,并发线程/进程可以发出相同的 SELECT FOR UPDATE 而无需锁定。

CREATE TABLE t (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
display_order INT
) ENGINE = InnoDB;

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
START TRANSACTION;
SELECT COALESCE(MAX(display_order), 0) + 1 from t FOR UPDATE;

..

这个概念与 SQL Server 的预期一样有效,但不适用于 MySQL。对我做错了什么有什么想法吗?

编辑

在 display_order 上添加索引不会改变行为。

最佳答案

这有一些有趣的,两个事务都准备好获得真正的锁。一旦其中一个事务尝试执行插入,锁就会出现。如果两个事务都尝试它,一个将得到一个死锁并回滚。如果只有其中一个尝试,它将获得锁定等待超时

如果您检测到锁定等待超时,您可以回滚,这将允许下一个事务执行插入。

所以我认为您很可能会很快遇到死锁异常或超时异常,这应该可以挽救这种情况。但是谈到完美的“可序列化”情况,这实际上是空表的不良副作用。该引擎不可能在所有情况下都是完美的,至少不能完成双事务插入..

我昨天在 potsgreSQl 文档上发送了一个关于真正的可串行性与引擎可串行性的有趣案例,检查这个例子它有趣:http://www.postgresql.org/docs/8.4/static/transaction-iso.html#MVCC-SERIALIZABILITY

更新:其他有趣的资源:Does MySQL/InnoDB implement true serializable isolation?

关于具有 innodb 和可序列化事务的 Mysql 不会(总是)锁定行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4668801/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com