数据库中隔离性的四种级别详解与例子

来源:互联网 发布:淘宝无线视频看不到了 编辑:程序博客网 时间:2024/06/05 10:09

事务的隔离性一般分为4个级别:

1. Read Uncommitted 未授权读取,实质上该级别允许读取未提交的数据,就是允许脏读。如果一个事务A读取了一条记录 r,并修改了该记录,事务A尚未提交时,事务B读取了r,如果事务A最后回滚了(因某种原因),那么事务B读了一条无效的记录。[1]给的例子,如果事务A对某一个值进行了 加1 操作 10 次,事务B能读取其中的中间值 2,3,4... ,这一系列中间值的读取就是未授权读取。

2. Read Committed 授权读取,也叫只读已提交数据,不允许脏读了。如果事务A对读取了一条记录 r1,并修改了该记录为 r2,事务A尚未提交时,事务B读取该记录,依然是原来的 r1,当事务A committed以后,事务B才能读取事务A修改后的值 r2,这就是授权读取,不会读中间数据,只读最终提交的数据。

但是,这有个问题,不可重复读问题(在一个事务范围内,执行2个相同的查询,查询的结果不同,因为有其他事务update了数据)。事务A事先读取了数据,事务B紧接了更新了数据,并提交了事务,而事务A再次读取该数据时,数据已经发生了改变 [2],造成了不可重复读。

3. Repeatable Read 可重复读,该隔离界别是多次读取同一条记录时,读取结果相同。这是禁止了不可重复读,实质上,当事务A读取记录r1时,不允许其他事务修改 r1,如果修改,需要等待事务A处理结束。说个额外有趣的,当事务A在修改数据时,发生了查询怎么办?实际应用中,是给数据和查询加了一个SCN (System change number),简单的说,为每一个查询添加一个时间戳,然后对比记录的时间戳,详见 [3]。

但是还是有问题,无法解决幻读问题,比如事务A 将 T表 中所有工资不到 10000元 的员工的工资改为10000元,在事务A执行结束尚未提交时,事务B又插入了一条(或删除操作)工资不满10000元的员工记录,然后再提交事务A,事务B。事务A好像发生了幻觉,没有操作成功一样,这是因为“可重复读”锁定的是,已经读取的记录,而不是锁定整张表(或者超出读取范围的数据),可重复读限制了事务本身涉及数据的update行为,但是无法限制事务自身以外的数据。我们可以使用表锁或者范围锁。

4. Serializable 串行化,这是最严苛的事务隔离级别。将所有事务串行化执行,简单暴力,直觉低效(但是也看场合)。

实际应用中,更多的是采用乐观锁,去保证数据的一致性,提高效率。最后说一下,乐观锁和悲观锁不是“锁”,以后补充。


文章来自:https://zhuanlan.zhihu.com/p/25014845

0 0
原创粉丝点击