mysql隔离级别
songtaiwu 人气:0隔离级别
一、mysql有四个事务隔离级别
每个级别都有字符或数字编号
- 读未提交 READ UNCOMMITTED | 0 : 存在脏读,不可重复度,幻读的问题。
- 读已提交 READ COMMITTED | 1 : 解决脏读问题,存在不可重复读,幻读的问题。
- 可重复读 REPEATABLE READ | 2 : 解决脏读,不可重复读的问题,存在幻读,默认隔离级别,使用MVCC机制实现可重复读。
- 序列化 SERIALIZABLE | 3 : 解决脏读,不可重复读,幻读,可保证事务安全,但完全串行执行,性能最低。
我有记忆方法,先是RU、RC, 记住UC顺序,联想到UC WEB。
二、为什么默认RR隔离级别?
RR级别作为mysql事务默认隔离级别,是事务完全和性能的折中。SERIALIZABLE级别是悲观地认为幻读时刻都会发生,故会自动地隐式地对事务所需资源加排他锁,其他事务访问此资源会被阻塞等待,故事务是安全的,但需要认值考虑性能。
三、RR隔离级别下手动加锁解决幻读理论基础
InnoDB的行锁锁定的是索引,而不是记录本身。索引映射的记录存在就加行锁,如果不存在则会加next-key lock/gap锁/间隙锁, 故InnoDB可以实现事务对某记录的预先占用。
脏读、不可重复读、幻读 及其解决方法
脏读
- 一个事务读取到另一个事务还没有提交的数据。解决方法:把事务隔离级别调整到READ COMMITTED。
不可重复读
- 一个事务先后读取同一条记录,但两次读取的数据不同,我们称之为不可重复读。解决方法:把事务隔离级别调整到REPEATABLE READ。
幻读
- 网上很多文章都说一个事务执行范围查询,两次select得到的条数不同,就叫幻读,这是错误的!!!
- 幻读并不是说两次读取获取的结果集不同,幻读是指某一次select操作得到的结果所表征的数据状态无法支持后续的业务操作,具体例子:select某记录是否存在,不存在,准备插入此记录,但执行insert时发现此记录已存在,无法插入,此时就发生了幻读。
- 还一种理解思路,就是因为先采用了"快照读",然后又用了"当前读",发现结果不同。比如先select是快照读,然后update、insert等,这时会用到当前读,发现操作出现未预料结果。
幻读解决方法
1、把事务隔离级别调整到SERIALIZABLE。2、RR隔离级别下,对select操作手动加行锁,select ... for update,这也序列化隔离级别下隐式会做的事。
参考文章
幻读 https:
事务隔离级别命令行操作
1、查看隔离级别
1)查看当前会话隔离级别
mysql> SELECT @@tx_isolation; +-----------------+ | @@tx_isolation | +-----------------+ | REPEATABLE-READ | +-----------------+ 1 row in set, 1 warning (0.00 sec)
2)查看系统隔离级别
mysql> select @@global.tx_isolation; +-----------------------+ | @@global.tx_isolation | +-----------------------+ | READ-UNCOMMITTED | +-----------------------+ 1 row in set, 1 warning (0.00 sec)
2、设置隔离级别
SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ|SERIALIZABLE]
1)设置当前会话
mysql> set session transaction isolation level repeatable read; Query OK, 0 rows affected (0.00 sec)
2)设置系统
mysql> set global transaction isolation level read uncommitted; Query OK, 0 rows affected (0.00 sec)3、命令行,开始事务时用
操作验证
自己在命令行去验证几种隔离级别下的读问题。
一、实现脏读
在不可提交读, 也就是READ UNCOMMITED情况下,会产生脏读。
二、操作验证--实现不可重复读
在可提交读, 也就是READ COMMITED情况下,会产生不可重复读。
三、操作验证--解决不可重复读
repeatable read(MySQL默认隔离级别),这时候能解决可重复读。
右边事务提交了,修改了age=29,左边再次查询,还是28。
四、操作验证--实现幻读
repeatable read(MySQL默认隔离级别),这时候还会出现幻读。
总结
加载全部内容