数据库的事务隔离级别
注意:设置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指的是多个事务串行执行
- 由于串行化解决了前面的问题,所以具体的测试就没有什么意义了