Menu Close

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

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默认级别是可重复读,默认不会造成脏读和可重复读问题。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注