Spring事务失效的原因

Spring事务失效:有事务注解的方法,出现了异常,却没有回滚数据。

一个事务的方法,出现了异常,没有正确地回滚数据,我们应该怎么排除错误?

我们以这句话为出发点,开始记下面的知识。

记忆口诀:

哭泣着,抓住错误的对象。

哭        ,泣                ,抓住        ,错误的                ,对象

数据库,事务管理器,抓住异常,错误的传播类型,代理对象

一、数据库

MySQL的数据库引擎,InnoDB支持事务,MyISAM不支持事务。

二、事务管理器

配置事务管理器

注解方式:@EnableTransactionManagement

配置方式:

<!--1 创建事务管理器-->

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

    <property name="dataSource" ref="dataSource"></property><!--注入数据源-->

</bean>

<!--开启事务注解-->

<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>

三、抓住异常

1、在事务方法内,使用了try...catch捕获异常,而catch里没有throw 要回滚的异常,事务不会回滚。

@Transactional(rollbackFor = RuntimeException.class)

Throwable
  Exception Error
SQLException RuntimeException VirtualMachineError
  NestedRuntimeException NullPointerException StackOverflowError OutOfMemoryError
  DataAccessException      
  NonTransientDataAccessException      
  DataIntegrityViolationException      

2、rollbackFor 默认对RuntimeException 和Error 以及它们的子类,做回滚。

 

四、错误的传播类型

传播类型默认是REQUIRED。

比如:在方法上加“@Transactional(propagation = Propagation.SUPPORTS)”,就相当于啥也没加。

参见:嘘!看紫色的光头强,送给猩猩一匹紫色的布,并且决不收它的钱钱。

五、代理对象

Spring事务是通过AOP,生成代理对象的代理方法,来实现的。

建议在实现类的方法上加 @Transactional 注解,不要在接口里加注解。

5.1、Transactional注解只能放在public方法上

默认配置时,@Transactional注解只能放在public方法上。放在private,protected方法上,事务无效,但不会报错。

让@Transactional在protected方法生效的配置。示例代码:gitee.com/SevenDayBabyface/jiwei

    @Bean(name = "transactionAttributeSource")

    public TransactionAttributeSource transactionAttributeSource() {

        return new AnnotationTransactionAttributeSource(false);

    }

 

               class AnnotationTransactionAttributeSource              注解事务属性源

abstract class AbstractFallbackTransactionAttributeSource   抽象的备用的事务属性源

         interface TransactionAttributeSource                                事务属性源

 

Create a custom AnnotationTransactionAttributeSource, supporting public methods that carry the {@code Transactional} annotation.

@param publicMethodsOnly whether to support public methods that carry the {Transactional} annotation only, or protected/private methods as well.

创建自定义 注释事务属性源,支持带有@Transactional注解的公共方法。

参数publicMethodsOnly:是只支持public方法,还是也支持protected方法。

5.2、在类的内部,自身调用

类中直接调用本类的方法,事务失效。因为事务通过aop实现。

Spring事务,调用代理类的对象的方法,才是使用了事务。

posted @ 2021-09-01 01:01  己为  阅读(488)  评论(0编辑  收藏  举报