Lim*_*beh 11 mysql innodb thread-safety atomicity
不使用显式事务,是:
update tokens set tokens = tokens + 1
Run Code Online (Sandbox Code Playgroud)
保证在InnoDB中是原子的吗?
我认为不是。没有我的 MySQL 隔离级别/备忘单可用,但我认为它在每行级别上是原子的(更新将使用范围锁 IIRC),但不是在每个表级别上。
\n\n现在,比 UPDATE 是否原子性更有趣的问题是 UPDATE 的非原子性何时是可观察的。答案是,READ UNCOMMITTED 隔离级别下的单个语句可以观察到 UPDATE 的非原子性,而 READ COMMITTED 隔离级别下的单个事务中的一系列相关语句可以观察到不同的更新。REPEATABLE READ 和 SERIALIZABLE 将 UPDATE 视为原子且一致的。
\n\n想象一下两个会话。会话 A 具有 SERIALIZABLE 隔离级别,并且执行以下操作:UPDATE tokens SET tokens = tokens + 1在具有 1000 行的表中。
SELECT sum(tokens) FROM tokens\xe2\x86\x92 此选择可以看到部分更新(即:某些行已更新,其他行未更新)。SELECT sum(tokens) FROM tokens\xe2\x86\x92 此选择无法看到部分更新,因此它看到 UPDATE 就好像它是原子的一样。SELECT sum(tokens) FROM tokens WHERE id BETWEEN 1 AND 100; SELECT sum(tokens) FROM tokens WHERE id BETWEEN 501 AND 600,然后某些程序逻辑将这两个值添加到 \xe2\x86\x92 这些 SELECT 可以看到不同的 MVCC 快照 \xe2\x86\x92 不同的更新,SELECT sum(tokens) FROM tokens WHERE id BETWEEN 1 AND 100; SELECT sum(tokens) FROM tokens WHERE id BETWEEN 501 AND 600,然后某些程序逻辑将这两个值添加到 \xe2\x86\x92 这些 SELECT 无法看到不同的 MVCC 快照 \xe2\x86\x92 他们看到相同的更新,