对于数据库中事务的隔离级别的理解

众所周知,数据库事务的隔离级别有四种:

read uncmmitted 读未提交,事务中的修改,即使没有提交,对其他事务也是可见的。

read commited 读提交(也称不可重复读),一个事务开始直到提交之前,所做的任何修改对其他事务都是不可见的。

repeatable read 可重复读,同一事务中,多次读取同样记录的结果是一致的。

serializable 可串行化,强制事务串行执行,避免幻读问题。

事务隔离级别和对应存在的问题如下图:

使用MySQL语句来理解事务的隔离级别。

有一个员工表employee,定义如下图,含三个字段id, name, salary。

一、读未提交

0 alice工资每月5000,

1 老板开始一个事务:将alice薪设置为10000。

2 尚未提交事务时,alice查询到自己的薪资是10000。

3 一会儿,老板回滚了事务。此时Alice的薪资还是5000。可是Alice读到了脏数据10000。

上面的事务执行update后,执行下面的语句,再执行上面事务中的回滚。

二、读提交

读提交,又称不可重复读,在该隔离级别下的同一个事务中,多次读相同记录,可能出现数据不一致。

开始事务,查询alice的薪资,(另有人修改了alice的薪资),再次查询alice的薪资,会发现两次查询得到的结果不一样。详情如下图:

可以看到上图事务中两次读取到的数据不一样。

三、可重复读

可重复读解决了上面不可重复读的问题。

其他事务的修改,对己事务不可见。在上图事务两次查询中间,执行了下图中的更新。可发现,上图事务中两次查询的结果一致,可重复读。

四、可串行化

图中先开始执行的事务虽然没有更新数据,但还没结束呢。这时另一个事务要更新数据。因为事务隔离级别是可串行化,强制事务串行执行,所以另一个事务就被阻塞了。长时间阻塞会超时退出:ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction。

另:还遗留一个问题,可重复读隔离级别下如何复现幻读现象?

现在再来看高性能MySQL书中的讲解,是不是容易理解下图了:)

参考链接:

如何编写事务https://dev.mysql.com/doc/refman/5.7/en/commit.html

如何设置数据库的隔离级别:https://dev.mysql.com/doc/refman/5.7/en/set-transaction.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章