mysql四种隔离机制和脏读、可重复读、幻读理解。

4次阅读
没有评论

共计 1279 个字符,预计需要花费 4 分钟才能阅读完成。

mysql 有四种隔离机制

屏幕快照 2017-08-22 下午 3.14.35.png

SELECT @@global.tx_isolation;  #查询全局隔离级别,默认为 REPEATABLE-READ.
SELECT @@session.tx_isolation; #查询当前会话隔离级别.

脏读测试

脏读的级别是 "read Uncommitted", 翻译过来也就是 "读,没有提交", 操作上就是会读取事务未提交的数据,比如会话 1 将值从 200 修改到 500,此时还未提交,会话 2 就可以直接读取到未提交的 500 数值。

  1. 开启两个 mysql 会话。
  2. 设置 mysql 会话隔离级别为 read Uncommitted,并开启事务.
SET SESSION TRANSACTION ISOLATION LEVEL read uncommitted; #设置为 " 读 未提交 " 级别
set autocommit = 0;
  1. 事务 1 查询数据
    屏幕快照 2017-08-22 下午 3.25.51.png
  1. 事务 2 修改 id 为 1 的 name 为 11. 此时并不提交.
    屏幕快照 2017-08-22 下午 3.28.28.png

5. 事务 1 再次查看数据.
屏幕快照 2017-08-22 下午 3.29.08.png

此时,虽然事务 2 还未提交,但是事务 1 已经可以读取到未提交而修改的数据。

影响

如果,这时候事务 2 并不提交数据,而是回滚了数据,则此时的读取的数据就是脏数据.

解决方案

使用 read commited 级别,如果事务 2 的修改没有 commit,则事务 1 读取的还是原数据.

可重复读测试

可重复读的级别对应的是 read committed 级别. 也就是“读已提交”,主要是在事务 1 中查询数据时,此时事务 1 未提交,事务 2 修改了某项数据,并提交。此时事务 1 再次查询,就会出现数据不一致的现象。

  1. 开启两个 mysql 会话。
  2. 设置 mysql 会话隔离级别为 read committed,并开启事务.
SET SESSION TRANSACTION ISOLATION LEVEL read committed; #设置为 " 读 未提交 " 级别
set autocommit = 0;

3. 在事务 1 中查询数据. 不 commit;
屏幕快照 2017-08-22 下午 3.53.44.png

4. 在事务 2 中修改数据,并 commit;
屏幕快照 2017-08-22 下午 3.54.16.png

5. 在事务 1 中再次查询数据,两次数据不一致.
屏幕快照 2017-08-22 下午 3.55.26.png

影响

重复读取数据不一致

解决方案

提高到 repeatable read(可重复读)隔离级别。

幻读测试

主要是在事务 1 操作时,事务 2 插入了一条数据, 造成数据不一致.

  1. 开启两个 mysql 会话。
  2. 设置 mysql 会话隔离级别为 repeatable read 及其以下的级别,并开启事务.
SET SESSION TRANSACTION ISOLATION LEVEL repeatable read; #设置为 " 可重复读 " 级别
set autocommit = 0;
  1. 事务 1 中查询所有数据。
  2. 事务 2 插入一条数据,并提交.
  3. 事务 1 查询数据,发现不一致,多了一条,此时事务 1 并未提交.

影响

数据查询造成不一致

解决方案

设置隔离级别为 serializable.

serializable, 序列化

serializable 可以解决幻读问题,事务 1 在查询过程中(未提交),此时在事务 2 中插入数据会进行等待. 事务 1 提交后,如果事务 2 未提交,则事务 1 进行等待。以保证数据一致性.

总结

隔离级别越大,数据就越发安全,但是并发就越低下。在现实业务中,需要权衡利弊。
另外 mysql 默认级别是可重复读,默认不会造成脏读和可重复读问题。

正文完
 0
admin
版权声明:本站原创文章,由 admin 于2015-12-21发表,共计1279字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)
验证码