Spring的事务传播机制

double

记录一下

一、propagation的七种事务传播行为

在 Spring 中定义了 7种传播行为

传播行为 含义 备注
PROPAGATION_SUPPORTS(有事务就支持,没有就没有) 如果存在一个事务,则支持当前事务,如果没有事务,则非事务的执行 -
PROPAGATION_NOT_SUPPORTED(忽略事务,不会被其他的事务回滚所影响) 总是非事务地执行,并挂起任何存在的事务 -
PROPAGATION_NEVER(不支持) 总是非事务地执行,如果存在一个活动事务,则抛出异常 -
PROPAGATION_REQUIRED(有就支持,没有就自动新建一个) 如果存在一个事务,则支持当前事务,如果没有事务则开启 这是 Spring 默认的传播行为
PROPAGATION_REQUIRES_NEW(创建一个新事务,不会被影响) 如果一个事务已经存在,则将这个存在的事务挂起 比如在信用卡管理的场景中,需要这个传播行为为每一个卡创建独立的事务
PROPAGATION_MANDATORY(必须要被嵌套到一个事务中) 如果已经存在一个事务,则支持当前事务,如果没有一个活动的事务,则抛出异常 -
PROPAGATION_NESTED(嵌套事务,可被捕获异常,被捕获的情况下不会影响其他事务回滚) 如果一个方法事务存在,则运行在一个嵌套的事务中,如果没有活动事务,按照 TransactionDefinition.PROPAGATION_REQUIRED 属性执行 -
① SUPPORTS

如果当前有事务,则使用事务,如果当前没有事务,则不使用事务。

② NOT_SUPPORTED

如果当前有事务,则把事务挂起,自己不使用事务去运行数据库操作

③ NEVER

如果当前有事务存在,则抛出异常

④ REQUIRED

使用当前的事务,如果当前没有事务,则自己新建一个事务,子方法是必须运行在一个事务中的,如果当前存在事务,则加入这个事务,成为一个整体。

⑤ REQUIRES_NEW

如果当前有事务,则挂起该事务,并且自己创建一个新的事务给自己使用;如果当前没有事务,则同 REQUIRED。

⑥ MANDATORY

该传播属性强制必须存在一个事务,如果不存在,则抛出异常。

⑧-① NESTED

如果当前有事务,则开启子事务(嵌套事务),嵌套事务是独立提交或者回滚;
如果当前没有事务,则同 REQUIRED;
但是如果主事务提交,则会携带子事务一起提交;
如果主事务回滚,则子事务会一起回滚。相反,子事务异常,则父事务可以回滚或不回滚。

二、疑问

  • 需要注意事务自调的场景
  • “REQUIRED、REQUIRES_NEW、NESTED” 三者的区别?

三、五种隔离级别

spring 在 TransactionDefinition 接口定义这些,以供 PlatfromTransactionManager 使用,PlatfromTransactionManager是Spring事务管理的核心接口。

public interface TransactionDefinition { int getPropagationBehavior(); //返回事务的传播行为。 int getIsolationLevel(); //返回事务的隔离级别,事务管理器根据它来控制另外一个事务可以看到本事务内的哪些数据。 int getTimeout(); //返回事务必须在多少秒内完成。 boolean isReadOnly(); //事务是否只读,事务管理器能够根据这个返回值进行优化,确保事务是只读的。 }

TransactionDefinition接口中定义五个隔离级别:
1)、ISOLATION_DEFAULT

这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别

2)、ISOLATION_READ_UNCOMMITTED

这是事务最低的隔离级别,它充许别外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读

3)、ISOLATION_READ_COMMITTED

保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。这种事务隔离级别可以避免脏读出现,但是可能会出现不可重复读和幻像读。

4)、ISOLATION_REPEATABLE_READ

这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。

5)、ISOLATION_SERIALIZABLE

这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻像读。

参考文章

Spring事务传播行为详解
Spring的事务传播机制实例
Spring 事务机制详解