zoukankan      html  css  js  c++  java
  • 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事务,调用代理类的对象的方法,才是使用了事务。

  • 相关阅读:
    备战考研算法笔记(四)快速排序
    VMware安装
    使用 Vagrant 打造跨平台开发环境
    类加载器,注解,动态代理
    IE兼容forEach/map/every/some等新方法
    不得不看的Java代码性能优化总结
    关于Oracle误操作--数据被Commit后的数据回退(闪回)
    JPA与Hibernate的关系
    Jenkins-GitHub-Gradle自动构建项目
    过滤器Filter
  • 原文地址:https://www.cnblogs.com/xsj891107/p/15212955.html
Copyright © 2011-2022 走看看