事务的隔离级别与Spring事务的传播机制

目录

事务的隔离性

事务的隔离级别

读未提交

读已提交

 可重复读

串行化

Spring事务的传播机制

支持当前事务

不支持当前事务

嵌套事务


事务的隔离性

事务的隔离性是事务的四大特性之一,数据库允许多个事务并发操作数据,为了尽可能地避免并发操作数据所带来的隐患,就需要依赖于事务地隔离性。事务的隔离性分为多个等级,包括:读未提交、读已提交、可重复读以及串行化,隔离等级依次提高。隔离性也是事务四大特性中唯一一个可以设置级别的特性。

事务的隔离级别

读未提交

事务最低隔离级别,该级别事务可以读取别的事务未提交时的数据。未提交的数据可能发生回滚,这时读取到的数据就是不存在的,这个数据称为脏数据,这个问题称为脏读

读已提交

该级别的事务读取到的数据都是提交过的数据,因此不会出现脏读问题。但是在该事务读取数据时,别的事务可以提交事务,因此在这次的事务中,可能出现使用同样的查询语句,查询出的结果却不同,这种现象称为不可重复读:

事务的隔离级别与Spring事务的传播机制_第1张图片

 可重复读

可重复读是MySQL默认的事务隔离级别,在此级别的事务执行过程中,其他的事务不能操作(包括读和写)已有的数据,因此不会出现不可重复读的情况(实际上该事务创建了一个快照,读取的数据都是基于这个快照的,而不是数据本身,因此事务对数据的修改在未提交时其他事务是看不到的)。但是却可以插入新的数据,这样相同的查询语句,返回的结果集就可能不同,这种情况就称为幻读:

事务的隔离级别与Spring事务的传播机制_第2张图片

串行化

事务隔离的最高级别,强制事务串行执行,没有并发操作,自然不会出现脏读、不可重复读和幻读的情况。

不可重复读和幻读的区别

  • 不可重复读指的是某条数据被修改(包括删除)而造成的前后读取不一致的情况
  • 幻读指的是由于新插入数据导致读取的数据集不一致。

Spring事务的传播机制

事务的隔离级别保证事务并发执行的稳定性,而事务的传播机制则保证一个事务在多个方法调用时的稳定性。在实际开发中,很少会直接通过事务来操作数据库中的数据,往往会有一条调用链,层层传递:

事务的隔离级别与Spring事务的传播机制_第3张图片

Spring事务的传播机制大体可分为三类:支持当前事务、不支持当前事务和嵌套事务。

支持当前事务

  • Propagation.REQUIRED: Spring事务的默认传播机制,如果当前调用链已经存在事务,则把该方法或节点加入事务;如果不存在事务,创建事务
  • Propagation.SUPPORTS: 如果当前调用链已经存在事务,则把该方法或节点加入事务;如果不存在事务,以非事务方式执行
  • Propagation.MANDATORY: 如果当前调用链已经存在事务,则把该方法或节点加入事务;如果不存在事务,抛异常

不支持当前事务

  • Propagation.REQUIRES_NEW: 创建新事务;如果当前调用链已经存在事务,把当前事务挂起,并创建新事务,新事务执行完再执行当前事务;
  • Propagation.NOT_SUPPORTED: 以非事务方式运行;如果当前存在事务,把当前事务挂起
  • Propagation.NEVER: 以非事务方式运行;如果当前存在事务,抛异常

嵌套事务

Propagation.NESTED: 当前存在事务,则创建事务嵌套进去;如果不存在事务,则创建事务;

这里的嵌套事务和上述加入事务不同,加入事务就成为一个整体,要么全部成功,要么全部失败;而嵌套事务可以一起成功,但如果嵌套的事务执行失败了,只回滚嵌套的事务,外部事务的提交不受影响。

假如调用链上某个方法或节点不指定事务的传播机制,则遵循其上层节点或方法的事务传播机制。

你可能感兴趣的:(数据库,mysql,spring,java)