共计 1279 个字符,预计需要花费 4 分钟才能阅读完成。
mysql 有四种隔离机制
SELECT @@global.tx_isolation; #查询全局隔离级别,默认为 REPEATABLE-READ.
SELECT @@session.tx_isolation; #查询当前会话隔离级别.
脏读测试
脏读的级别是 "read Uncommitted", 翻译过来也就是 "读,没有提交", 操作上就是会读取事务未提交的数据,比如会话 1 将值从 200 修改到 500,此时还未提交,会话 2 就可以直接读取到未提交的 500 数值。
- 开启两个 mysql 会话。
- 设置 mysql 会话隔离级别为 read Uncommitted,并开启事务.
SET SESSION TRANSACTION ISOLATION LEVEL read uncommitted; #设置为 " 读 未提交 " 级别
set autocommit = 0;
- 事务 1 查询数据
- 事务 2 修改 id 为 1 的 name 为 11. 此时并不提交.
5. 事务 1 再次查看数据.
此时,虽然事务 2 还未提交,但是事务 1 已经可以读取到未提交而修改的数据。
影响
如果,这时候事务 2 并不提交数据,而是回滚了数据,则此时的读取的数据就是脏数据.
解决方案
使用 read commited 级别,如果事务 2 的修改没有 commit,则事务 1 读取的还是原数据.
可重复读测试
可重复读的级别对应的是 read committed 级别. 也就是“读已提交”,主要是在事务 1 中查询数据时,此时事务 1 未提交,事务 2 修改了某项数据,并提交。此时事务 1 再次查询,就会出现数据不一致的现象。
- 开启两个 mysql 会话。
- 设置 mysql 会话隔离级别为 read committed,并开启事务.
SET SESSION TRANSACTION ISOLATION LEVEL read committed; #设置为 " 读 未提交 " 级别
set autocommit = 0;
3. 在事务 1 中查询数据. 不 commit;
4. 在事务 2 中修改数据,并 commit;
5. 在事务 1 中再次查询数据,两次数据不一致.
影响
重复读取数据不一致
解决方案
提高到 repeatable read(可重复读)隔离级别。
幻读测试
主要是在事务 1 操作时,事务 2 插入了一条数据, 造成数据不一致.
- 开启两个 mysql 会话。
- 设置 mysql 会话隔离级别为 repeatable read 及其以下的级别,并开启事务.
SET SESSION TRANSACTION ISOLATION LEVEL repeatable read; #设置为 " 可重复读 " 级别
set autocommit = 0;
- 事务 1 中查询所有数据。
- 事务 2 插入一条数据,并提交.
- 事务 1 查询数据,发现不一致,多了一条,此时事务 1 并未提交.
影响
数据查询造成不一致
解决方案
设置隔离级别为 serializable.
serializable, 序列化
serializable 可以解决幻读问题,事务 1 在查询过程中(未提交),此时在事务 2 中插入数据会进行等待. 事务 1 提交后,如果事务 2 未提交,则事务 1 进行等待。以保证数据一致性.
总结
隔离级别越大,数据就越发安全,但是并发就越低下。在现实业务中,需要权衡利弊。
另外 mysql 默认级别是可重复读,默认不会造成脏读和可重复读问题。