CREATE TABLE `users` ( `id` smallint(6) NOT NULL AUTO_INCREMENT, `name` varchar(25) DEFAULT NULL, `age` tinyint(4) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8; ALTER table `users` auto_increment=1; INSERT INTO users(`name`,`age`) VALUES('lyf_16',16); INSERT INTO users(`name`,`age`) VALUES('xtf_17',17);
当前事务(currTx)SQL | 当前事务(currTx)结果 | 其他事务(otherTx)SQL | 其他事务(otherTx)结果 |
---|---|---|---|
SELECT @@GLOBAL.TX_ISOLATION AS 'GLOBAL-tx',@@SESSION.TX_ISOLATION AS '@@SESSION-tx'; | SELECT @@GLOBAL.TX_ISOLATION AS 'GLOBAL-tx',@@SESSION.TX_ISOLATION AS '@@SESSION-tx'; | ||
START TRANSACTION; | |||
START TRANSACTION; | |||
SELECT * FROM users; | |||
INSERT INTO users(name,age) VALUES('zbz',18);UPDATE users SET age=99 WHERE id=1;DELETE FROM users WHERE id=2;SELECT * FROM users; | |||
SELECT * FROM users; | 同上 | ||
COMMIT; | |||
SELECT * FROM users; | 同上 | ||
UPDATE users SET age=88 WHERE id=2;SELECT * FROM users; | 同上 | ||
UPDATE users SET age=88 WHERE id=1;SELECT * FROM users; | |||
UPDATE users SET age=99;SELECT * FROM users; | |||
START TRANSACTION;INSERT INTO users( name, age) VALUES('xtf',28); | 锁等待,最终超时:lock_data:supremum pseudo-record [Err] 1205 - Lock wait timeout exceeded; try restarting transaction | ||
SELECT * FROM users; | 同上 | ||
COMMIT;SELECT * FROM users; |
总结如下:
REPEATABLE-READ: 可重复读隔离级别,会出现幻读
1. 其他事务做更新:当前事务查询结果:不变
2. 其他事务做删除:当前事务查询结果:不变
3. 其他事务做插入:当前事务查询结果:不变
4. 在1、2、3基础上,当前事务做更新影响数为0时,当前事务查询结果:不变
5. 在1、2、3基础上,当前事务做更新影响数大于0时
5.1. 更新到了其他事务新增的记录,则当前事务查询结果包含新增记录更新列值为最新值
5.2. 更新到了其他事务删除的记录,当前事务查询结果仍然包含此条删除记录,并且更新列值不变
5.3. 更新到了其他事务更新的记录,则当前事务查询结果包含更新记录更新列值为最新值
相当于:
1. 只有全表操作时,当前事务才会加载到其他事务新增/更新的记录
2. 只有变更到相应记录时,其他事务对此条记录的更新才会在当前事务体现
3. 当前事务对已被其他事务删除的记录,不更新,即仍然保留当前事务副本(即当前事务中查询还可见,实际却操作不了)
4. 当前事务的查询操作,不会对其他事务的已提交操作可见。走到当前事务有做出变更。
文章来源: 隔离级别之可重复读级别解读