mysql笔记系列——事务隔离级别详细分析

数据库的事务隔离级别

注意:设置A事务的会话事务隔离隔离,只是在A事务在读取B事务才起作用,对于A事务而言,不管B的会话事务隔离级别是什么都不要紧!!!(与全局事务隔离级别无关)

1、读取未提交内容read uncoommitted,对应的操作为脏读,提高隔离级别可解决此问题
2、读取提交内容read committed,能发生不可重复读的问题,提高隔离级别可解决此问题
3、可重复读repeatable read,对新插入的数据会发生幻读现象,提高隔离级别可解决此问题,也有别的解决方案
4、可串行化serializable,隔离级别的最高级,解决了前面的所有问题

mysql的事务隔离级别

1、mysql的存储引擎为InnoDB,而InnoDB的事务隔离级别默认为可重复读repeatable read
2、mysql事务隔离级别有全局global和会话session事务隔离级别,分别为global.tx_isolation和session.tx_isolation

mysql下测试事务隔离级别

1、测试读取未提交内容read uncommitted

准备工作:打开两个mysql命令窗口,这里命名为A和B

A和B事务隔离级别不作改变,均为默认值repeatable read,A和B的事务自动提交模式设置为关闭,关闭命令为:

set autocommit = off;

set autocommit = 0;

注意:测试过程中不要插入中文数据,默认的编码格式会导致无法插入数据和显示乱码

测试流程:

  • B中建一个表,插入一条数据,不commit
  • A中查询不到数据
  • B修改会话事务隔离级别为read uncommitted
  • A这时执行查询还是查不到,这是因为改变B的事务隔离级别没用,要改变A的事务隔离级别
  • A修改会话事务隔离级别为read uncommitted
  • A进行commit(这里commit是因为上步骤的修改还没生效),这时能查询到未commit的数据

2、测试读取提交内容read committed

接着测试1开始测试流程:

  • A修改会话事务隔离级别为read committed,并commit,否则还是read uncommitted
  • B中插入一条数据,不commit
  • A中查询不到插入的数据
  • B中commit
  • A能查询到B中插入的数据了
  • B中修改刚插入的数据,不commit
  • A查询不到修改后的数据 *
  • B中commit
  • A中查询到了修改后的数据 *

说明:打星号2步查询到的结果不一样,这种现象就叫不可重复读,也就是相同的查询读取的结果不一样!

3、测试可重复读repeatable read

接着测试2开始测试流程:

修改测试:
- A修改会话事务隔离级别为repeatable read,并commit,否则还是read committed
- B中修改一条数据,不commit
- A中查询不到修改的数据
- B中commit
- A能还是查询不到B中修改的数据,依然是修改前的数据,这就叫可重复读
- A中commit
- A中这时能查询到修改后的数据了

插入测试:
- B中插入的一条数据,不commit
- A查询不到插入的数据
- B中commit
- A能还是查询不到B中插入的数据,依然是插入前的数据,这也是可重复读
- A中commit
- A中这时能查询到插入的数据了

幻读测试:
- A中更新所有数据,不commit
- B中插入一条数据,按回车执行时,则会等待A的commit,直到超时
- A中commit,则B执行插入,但不commit
- A中查询不到B插入的数据
- B中commit
- A中这时能查询到插入的数据了,这就是幻读,也就是两次查询的结果不一样,发现还有一条数据没有修改,就像是幻觉一样!

4、测试可串行化serializable

可串行化serializable指的是多个事务串行执行

  • 由于串行化解决了前面的问题,所以具体的测试就没有什么意义了

你可能感兴趣的:(mysql)