深入理解mysql事务隔离级别
Posted imfx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入理解mysql事务隔离级别相关的知识,希望对你有一定的参考价值。
mysql支持4种事务隔离级别分别为
Read Uncommitted 读未提交
Read Committed 读已提交
Repeatable Read 可重复读 *注意这个概念容易混,下面细说
Serializable 串行化事务操作
1.Read Uncommitted 读未提交
事务隔离级别设为Read Uncommitted时,能查询到其他事务已修改但尚未提交的数据,若后续其他事务发生回滚,则造成了脏读。是最低的事务隔离级别
2.Read Committed 读已提交
事务隔离级别设为Read Committed时,就不会查询到其他事务已修改但尚未提交的数据了,读取的都是其他事务已提交过的数据,避免了脏读。
但是会出现一种新的问题 不可重复读问题 如下
在Read Committed 级别下开启一个事务,先执行
select * from books where name = “计算机原理”
查询到图书信息 包括图书的数量,采购价格等,但此时另外一个事务修改了该图书的数量,并且进行了提交,那么接下来第一个事务
再使用 select * from books where name = “计算机原理” 查询时会发现图书的数量发生了变化,出现了前后查询不一致的问题,即不可重复读问题
3.Repeatable Read 可重复读
事务隔离级别设为Repeatable Read可以避免不可重复读问题 但要注意 并不是禁止其他事务去修改,或者阻塞其他事务的更改,而是在该隔离级别下,同样的条件多次查询 使用的是一个快照,即第一次查询的结果,其他事务仍然可以对数据进行更改并提交。尽管使用的是快照结果但仍然可以保证事务的一致性,可通过如下方式进行验证
例如
事务A隔离级别设为Repeatable Read
开启事务A 查询 计算机原理图书的数量
select total from books where name = “计算机原理”
total 值为20,
然后其他事务修改计算机原理图书数量为29并进行了提交,
事务A再次执行
select total from books where name = “计算机原理”
total 值仍未20(上面有解释,这是一个快照)
事务A执行 更新操作
update books set total = total - 1 where name = "计算机原理"
再次查询 select total from books where name = “计算机原理” 会发现total为28 保证了事务的一致性。
在Repeatable Read隔离级别下,仍然有新的问题,即幻读
幻读是指,在一个事务中,第一次查询某条记录,发现没有,但是,当试图更新这条不存在的记录时,竟然能成功,并且,再次读取同一条记录,它就神奇地出现了。
4.Serializable 串行化事务操作
事务的最高隔离级别 可避免脏读,不可重复读,幻读
在该隔离级别下,开启事务 执行查询语句,在该查询范围内的数据如有其它事务进行更改或新增删除等,会被阻塞,强制依顺序执行事务,
例如
事务A隔离级别设为Serializable
开启事务 执行 select *from books where name = “计算机原理”
其它事务只要新增,更改,删除 name为“计算机原理”的行都会被阻塞强制按事务先后顺序执行,即事务A结束后,他们才能继续执行。
若事务A开启事务 执行 select *from books 则其它事务对这张表执行的增删改都会被阻塞,被迫按事务顺序执行,即事务A结束后,他们才能继续执行。
以上示例 都已在mysql上进行了验证 另外mysql事务默认隔离级别为Repeatable Read
以上是关于深入理解mysql事务隔离级别的主要内容,如果未能解决你的问题,请参考以下文章