insert在竞争条件下选择和更新

c3frrgcw  于 2021-06-18  发布在  Mysql
关注(0)|答案(2)|浏览(262)

1:如果我跑的话

INSERT INTO foo SELECT MAX(X) FROM bar;

我能确定我刚刚插入了 Xbar table?没有其他会话能够操纵 bar 后面的table SELECT 部分已完成,但在 INSERT 完成了吗?

2:如果我跑了

UPDATE foo SET x = 0 WHERE y = 100;

当时钟到达00:00并且查询需要2分钟时,我是否可以确保 y = 100 00:00已经更新了吗?其他会话都没有改变 y = 100y = 80 在我的查询完成之前?

3:这与#2有关。如果在00:01另一个会话 UPDATE 通过更改将更改为一行 y = 99y = 100 ,我以前的查询是否尝试 UPDATE 这一排?

8ljdwjyq

8ljdwjyq1#

事务用于保证数据库的状态。可重复读取,因此当读取最大值时,您可以一次又一次地读取它,它将保持不变。
https://dev.mysql.com/doc/refman/5.6/en/innodb-transaction-isolation-levels.html#isolevel_repeatable-阅读
然后设置事务
https://dev.mysql.com/doc/refman/5.6/en/set-transaction.html
然后代码更新x=(从z中选择max(y))
然后提交事务
我可能错过了一些东西,但总的来说,这就是它如何做的报告。

esyap4oy

esyap4oy2#

如果不使用显式事务,则每个查询本身都被视为一个事务。所以一个查询 INSERT 以及 SELECT 就像你的#1可以依赖于一致性。大致相当于:

START TRANSACTION;
SET @max = (SELECT MAX(x) FROM bar);
INSERT INTO foo VALUES (@max);
COMMIT;

但是,事务不会在事务启动时生成整个数据库的快照。innodb使用每记录锁定。所以在#2和#3中,如果你有一个会话 y 当会话b执行您显示的查询时,b更新的记录可能包括也可能不包括a修改的记录,这取决于这些特定更改的相对顺序。另一方面,myisam使用表级锁,所以这应该是不可能的;无论哪个查询首先启动,都将锁定 foo 表,另一个查询将等待它完成,然后再开始扫描表。

相关问题