前文
首先理解事务的ACID的隔离性 并发带来的问题,脏读
、不可重复读
、幻读
的问题。
脏读: 一个事务读取了另一个事务未提交的数据,导致数据不一致。【事务2未提交】
不可重复读: 一个事务前后两次读取的同一数据不一致 【事务2已提交】
幻读: 一个事务两次查询的结果集记录数不一致,返回的记录行数有差异
不可重复读跟脏读的区别
不可重读就是第二个事务提交了对数据的修改,脏读是在第二个事务未提交回滚了对数据的修改。
虽然在不可重复读
前后数据不一样,由于事务2最终提交了修改,在事务1第二次读到数据,实际上是有效的。
而不像脏读
事务2最终是回滚对数据修改,导致事务1第二次读取数据是无效的数据。
所以说不可重复读是还可以接受的。
InnoDB的几种事务隔离级别
支持4中隔离级别,一个事务对另一个事务并发进行修改时,可以相互影响的程度。
隔离级别 | 脏读 | 不可重复读 | 幻读 | 隔离性 | 并发性 |
---|---|---|---|---|---|
串行化(SERIALIZABLE) | N | N | N | 最高 | 最低 |
可重复读(PEREATABLE READ) | N | N | Y/N | ||
读以提交(READ COMMITTED) | N | Y | Y | ||
读未提交(READ UNCOMMITTED) | Y | Y | Y | 最低 | 最高 |
4.1 串行化(顺序读)
对事务强制的排序,使各个事务顺序执行,这样就避免了各个之间的相互冲突,从而解决脏读、不可重复读、幻读
的问题。
由于所有的事务是顺序执行,虽然在这隔离性最高,反而并发性是最差的 , 所以的事务都是顺序执行并不存在并发。
4.2 可重复读
可以 保证在同一个事务中,多次读取同一数据时返回的结果是相同的,可以避免脏读、不可重复读
的问题,但是不能避免幻读
的问题。
如果在Innodb中利用了Next-key
引用下一个键索机制,锁定一个范围,并且锁定记录本身,避免幻读的现象。
在这个级别不断可以做到顺序读隔离性,同时事务的并发性做到很好的保证。(INNODB默认使用级别)
4.3 读以提交
保证事务只能看到已经被提交的事务的关联数据的修改,只能避免脏读
,无法避免不可重复读、幻读
的产生。
隔离性比较差,但是并发性很高,由于查到都是其他事务修改后的数据,有很多人喜欢这种隔离级别,在并发要求性比较高的场景中。
sqlserver、PostGreSQL 默认使用的一种隔离级别
4.4 读未提交
如名字一样, 一个事务可以读到另一个事务未提交的数据,因此无法避免脏读、不可重复读、幻读
的产生。
隔离性最差,同时是并发性最高的的隔离级别。
小结
对事务来说,在不同的隔离级别下所执行的结果也不一样,隔离级别越高,数据的完整性一致性越好,同时并发性也越差。
- session:当前会话,也就是当前连接立即生效。
- global:全局,
不包含当前连接
,之后新获取的连接都会生效。
修改(当前会话)事务隔离级别
set session TRANSACTION ISOLATION LEVEL [SERIALIZABLE | PEREATABLE READ | READ COMMITTED | READ UNCOMMITTED ] #修改隔离级别
查看事务里级别
show variables like "%iso%" #查看事务隔离级别
评论 (0)