zoukankan      html  css  js  c++  java
  • 注解@Transactional事务失效的常见场景

    在《Spring Boot事务管理》中,小编介绍了注解@Transactional的基本属性和使用方法,这里介绍事务失效的八种场景,使大家对注解@Transactional有一个更深刻的认知。

      被注解修饰的方法为非public类型。之所以会失效,是因为在Spring AOP 代理中,TransactionInterceptor (事务拦截器)在目标方法执行前后进行拦截,DynamicAdvisedInterceptor(CglibAopProxy 的内部类)的 intercept 方法或 JdkDynamicAopProxy 的 invoke 方法会间接调用AbstractFallbackTransactionAttributeSource的 computeTransactionAttribute 方法,获取Transactional 注解的事务配置信息。

    protected TransactionAttribute computeTransactionAttribute(Method method,
        Class<?> targetClass) {
            // Don't allow no-public methods as required.
            if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
            return null;
    }
    

    computeTransactionAttribute方法会检查目标方法的修饰符是否为 public,不是 public则不会获取@Transactional 的属性配置信息。

      异常被catch块吃掉,导致回滚失败。

      异常抛出类型错误,例如属性rollbackFor默认回滚的是RuntimeException,而代码抛出了其父类的异常Exception,这时是不可以回滚的。如果抛出了RuntimeException的子类异常,如NullPointerException,则可以回滚。

      本类方法直接调用。比如有一个类Test,它里面有两个方法,方法A没有声明注解事务,而public类型的B方法有,而且是A调用了B。则外部调用方法A之后,方法B的事务是不会起作用的。此时会用this关键字直接请求B方法,没有经过 Spring AOP的代理类去调用方法,从而没有开启事务管理,默认只有在外部调用事务才会生效。这也是经常犯错误的一个地方。

      Bean没有被spring容器管理

      数据库引擎不支持事务。以 MySQL 为例,其 MyISAM 引擎是不支持事务操作的,InnoDB 才支持,一般要支持事务都会使用 InnoDB。

      数据源没有配置事务管理器。实现接口方法,使得返回数据库事务管理器:

    @Bean 
    PlatformTransactionManager transactionManager(DataSource dataSource) {
           return new DataSourceTransactionManager(dataSource);
    }
    

      方法事务传播行为设置不支持事务:propagation = Propagation.NOT_SUPPORTED or TransactionDefinition.PROPAGATION_NEVER。

    TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。所以,在当前没有事务的场景下使用此传播行为属性,则以非事务的方式继续运行。

    Reference

    Spring事务失效的 8 大原因,这次可以吊打面试官了


      读后有收获,小礼物走一走,请作者喝咖啡。

    赞赏支持

  • 相关阅读:
    Python 机器学习实战 —— 监督学习(上)
    Python 基础教程 —— Pandas 库常用方法实例说明
    Python 基础教程 —— 网络爬虫入门篇
    2个周末,历时100+小时,YourBatman新版Blog正式上线
    玩转IDEA项目结构Project Structure,打Jar包、模块/依赖管理全搞定
    谁再把IDEA的Project比作Eclipse的Workspace,我就跟谁急
    IntelliJ IDEA 20周岁啦,为期2天的周年庆活动对开发者免费开放
    数字跳动 jqjs
    js多项筛选功能
    调用本地摄像头实现拍照拍照截取照片 jqjs 、 vue
  • 原文地址:https://www.cnblogs.com/east7/p/14922934.html
Copyright © 2011-2022 走看看