Spring - 事务之隔离级别
发布日期:2021-06-30 23:47:31 浏览次数:2 分类:技术文章

本文共 1276 字,大约阅读时间需要 4 分钟。

事务的第二个维度就是隔离级别(isolation level)。隔离级别定义了一个事务可能受其他并发事务影响的程度。 

(1)并发事务引起的问题

在典型的应用程序中,多个事务并发运行,经常会操作相同的数据来完成各自的任务。并发虽然是必须的,但可能会导致以下的问题。

  • 脏读(Dirty reads)——脏读发生在一个事务读取了另一个事务改写但尚未提交的数据时。如果改写在稍后被回滚了,那么第一个事务获取的数据就是无效的。
  • 不可重复读(Nonrepeatable read)——不可重复读发生在一个事务执行相同的查询两次或两次以上,但是每次都得到不同的数据时。这通常是因为另一个并发事务在两次查询期间进行了更新。
  • 幻读(Phantom read)——幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录。

不可重复读与幻读的区别

不可重复读的重点是修改:

同样的条件,你读取过的数据,再次读取出来发现值不一样了 
例如:在事务1中,Mary 读取了自己的工资为1000,操作并没有完成

con1 = getConnection();  select salary from employee empId ="Mary";

在事务2中,这时财务人员修改了Mary的工资为2000,并提交了事务

con2 = getConnection();  update employee set salary = 2000;  con2.commit();

在事务1中,Mary 再次读取自己的工资时,工资变为了2000

//con1  select salary from employee empId ="Mary";

在一个事务中前后两次读取的结果并不一致,导致了不可重复读。

幻读的重点在于新增或者删除: 

同样的条件,第1次和第2次读出来的记录数不一样 
例如:目前工资为1000的员工有10人。事务1 读取所有工资为1000的员工。

con1 = getConnection();  Select * from employee where salary =1000;

共读取10条记录

这时另一个事务向employee表插入了一条员工记录,工资也为1000

con2 = getConnection();  Insert into employee(empId,salary) values("Lili",1000);  con2.commit();

事务1再次读取所有工资为1000的员工

//con1  select * from employee where salary =1000;

共读取到了11条记录,这就产生了幻像读。

从总的结果来看,似乎不可重复读和幻读都表现为两次读取的结果不一致。但如果你从控制的角度来看,两者的区别就比较大。 

对于前者,只需要锁住满足条件的记录。 
对于后者,要锁住满足条件及其相近的记录。

 

(2)隔离级别

 

转载地址:https://lux-sun.blog.csdn.net/article/details/84500544 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Spring - 事务之编程式
下一篇:Spring - 事务之传播行为

发表评论

最新留言

第一次来,支持一个
[***.219.124.196]2024年04月19日 22时24分33秒