Spring中的@Transactional注解配置、rollbackFor = Exception.class

在 Spring 中,@Transactional 注解用于定义事务的范围。事务用于确保一组数据库操作要么全部成功提交,要么全部回滚,以保持数据的一致性和完整性。在某些情况下,当抛出异常时,Spring 默认情况下会回滚事务,但有一些情况需要额外的配置。

  • @Transactional 注解默认情况下捕获error和运行时异常RuntimeException。当@Transactional不配置任何的内容的时候,默认只会对运行时异常及其子类生效, 其余一概不生效。事务管理器会识别到这类异常来进行回滚,但是非RuntimeException的异常抛出时,事务管理器是不会回滚事务的。
  • 如果加了属性rollbackFor = Exception.class,那么事务管理器会捕获到Exception及子类的所有异常和Error来回滚事务。

    一、配置

    在 Spring 框架中使用 @Transactional 注解来管理事务需要进行一些配置。以下是一些必要的配置步骤:

    1. 添加spring-tx依赖:

    在Spring项目中,要使用@Transactional注解进行事务管理,您需要添加spring-tx依赖。在Maven项目中,您可以在项目的pom.xml文件中添加以下依赖:

     org.springframework spring-tx 5.3.10 

    在添加了spring-tx依赖之后,您就可以在Spring中使用@Transactional注解来管理事务了。

    2. xml配置:

    1. 需要在 Spring 配置文件中启用事务管理功能,改配置文件ioc.xml/spring-mybatis
     xmlns:tx="http://www.springframework.org/schema/tx"
    		http://www.springframework.org/schema/tx
            http://www.springframework.org/schema/tx/spring-tx.xsd
    
    1. 配置事务管理器: 事务管理器负责管理事务的生命周期,包括开始、提交和回滚事务。需要配置一个适当的事务管理器,例如 DataSourceTransactionManager。
       

    3. 只让mvc.xml扫描 controller包

    💡 注意: mvc.xml中没有配置开启事务注解扫描, 并且mvc.xml又是全包扫描, 最终会导致被扫描到的类的确都装载到ioc容器中, 唯独没有生效事务相关注解

    💡 解决方式: 只让mvc.xml扫描 controller包

    4. 添加 @Transactional 注解:

    现在可以在需要进行事务管理的方法上添加 @Transactional 注解。这会告诉 Spring 在方法执行期间开启一个事务,并在方法完成时根据情况提交或回滚事务。

    设置事务属性: 可以在 @Transactional 注解上设置一些事务属性,如隔离级别、传播行为、是否只读等。这些属性会影响事务的行为。

    二、注解 @Transactional 的配置

    在Spring框架中,@Transactional 注解用于进行事务管理。通过该注解,可以在方法或类级别上指定事务的行为。下面介绍了一些 @Transactional 注解的常见用法和配置。

    1. 默认异常回滚规则*

    默认情况下,@Transactional 注解会捕获运行时异常和其子类,然后触发事务回滚。这意味着在方法抛出运行时异常时,事务会被回滚。例如:

    @Transactional
    public void someMethod() { // 如果发生运行时异常,事务会回滚
    }
    

    💡默认情况下,在遇到运行时异常和Error,spring事务会进行回滚,

    而遇到非运行时异常Exception则不会回滚

    💡 可以通过rollbackFor指定需要回滚的受检查异常,指定异常之后,被指定的异常和该异常的子类都会得到回滚,并且运行时异常和Error异常仍然会得到回滚

    2. 使用 rollbackFor 参数*

    如果希望在特定类型的异常发生时也触发事务回滚,可以使用 rollbackFor 参数。通过在 @Transactional 注解中配置 rollbackFor 参数,可以指定哪些异常会触发事务回滚。

    @Transactional(rollbackFor = Exception.class)
    public void someMethod() { // 无论抛出何种异常,事务都会回滚
    }
    

    3. 自定义异常触发回滚

    您还可以根据业务逻辑的需要自定义异常类,并将其配置在 rollbackFor 参数中。这样,在抛出这些自定义异常或其子类时,事务会触发回滚。

    @Transactional(rollbackFor = CustomException.class)
    public void someMethod() throws CustomException { // 抛出 CustomException 或其子类,事务会回滚
    }
    

    4. 关于提交与回滚

    默认情况下,Spring 事务在遇到运行时异常时会触发回滚,但在提交时并不会立即提交到数据库。Spring 使用了**手动提交(manual commit)**的机制,它会在事务方法执行结束后,根据是否抛出异常来决定是提交事务还是回滚事务。

    这种机制的优点在于,在出现异常时可以保持数据库的数据不受影响,只是对临时文件进行了更改。实际的提交或回滚操作会在事务方法执行完毕后自动进行。

    5. 注意事项

    使用 @Transactional 注解进行事务管理时,需要仔细考虑异常的处理和事务回滚策略。过于宽泛地回滚事务可能会导致一些问题,因为某些异常可能是可以恢复的,但被错误地回滚了。在使用 rollbackFor 参数时,请根据业务逻辑和异常处理进行慎重的配置,以确保数据的一致性和可靠性。

    三、事务的使用范围:只有innodb表引擎支持事务

    mysql5.7和8版本开始, 默认的mysql表存储引擎是InnoDB存储引擎, 5.7以前用的MyASIAM表引擎

    只有innodb表引擎支持事务, myasim引擎不支持事务

    四、spring事务默认的传播行为是 REQUIRED

    事务传播行为(propagation behavior)指的就是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何运行。

    Spring在TransactionDefinition接口中规定了7种类型的事务传播行为。

    •事务传播行为是Spring框架独有的事务增强特性。

    例如:methodA方法调用methodB方法时,methodB是继续在调用者methodA的事务中运行呢,还是为自己开启一个新事务运行,这就是由methodB的事务传播行为决定的。

    PROPAGATION_REQUIRED

    如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,这是最常见的选择,也是Spring默认的事务传播行为。

    综上所述,@Transactional 注解是一个强大的工具,可以帮助管理事务,并确保数据的完整性和可靠性。根据业务需求,灵活地配置 rollbackFor 参数,可以使事务在恰当的时候回滚,从而维护数据的一致性。