Spring事务管理

一、事务的简介

事务是一组操作的集合,它是一个不可分割的工作单位。事务会把所有的操作作为一个整体,一起向数据库提交或者是撤销操作请求。所以这组操作要么同时成功,要么同时失败。

场景举例:

比如要执行一个删除一个分类及其该分类下所有文章的操作,如果不将他们作为一个事务,那么加入中途出现异常,只删除了文章,而没有删除分类,这样就出问题了。如果将他们作为一个事务,那么中间出现异常后,会进行回滚,文章和分类都没有删除。

二、Spring的事务管理

在spring中我们通过@Transactional注解来实现事务管理(具体使用可以见SpringBoot注解一篇)

可以在application.yml配置文件中开启事务管理日志,这样就可以在控制看到和事务相关的日志信息了

1
2
3
4
#spring事务管理日志
logging:
level:
org.springframework.jdbc.support.JdbcTransactionManager: debug

三、事务进阶

了解@Transactional 注解当中的两个重要属性:

  • 异常回滚的属性:rollbackFor
  • 事务传播行为:propagation

1. rollbackFor

默认情况下,只有出现RuntimeException(运行时异常)才会回滚事务。

如果还需要回滚指定类型的异常,那就需要配置rollbackFor属性

1
@Transactional(rollbackFor=Exception.class)

2. propagation

场景:两个事务方法,一个A方法,一个B方法。在这两个方法上都添加了@Transactional注解,就代表这两个方法都具有事务,而在A方法当中又去调用了B方法。

此时就出现了问题,A方法运行的时候,首先会开启一个事务,在A方法当中又调用了B方法, B方法自身也具有事务,那么B方法在运行的时候,到底是加入到A方法的事务当中来,还是B方法在运行的时候新建一个事务?这个就涉及到了事务的传播行为。

事务传播行为:

  • 就是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行事务控制。

propagation 这个属性是用来配置事务的传播行为的。

在@Transactional注解的后面指定一个属性propagation,通过 propagation 属性来指定传播行为。

属性值 含义
REQUIRED 【默认值】需要事务,有则加入,无则创建新事务
REQUIRES_NEW 需要新事务,无论有无,总是创建新事务
SUPPORTS 支持事务,有则加入,无则在无事务状态中运行
NOT_SUPPORTED 不支持事务,在无事务状态下运行,如果当前存在已有事务,则挂起当前事务
MANDATORY 必须有事务,否则抛异常
NEVER 必须没事务,否则抛异常

重点关注前两个

  • REQUIRED :大部分情况下都是用该传播行为即可。

  • REQUIRES_NEW :当我们不希望事务之间相互影响时,可以使用该传播行为。比如:下订单前需要记录日志,不论订单保存成功与否,都需要保证日志记录能够记录成功。