zoukankan      html  css  js  c++  java
  • Spring事务失效的原因

    一. mysql 存储引擎不支持事务

    二. 数据源没有配置事务管理器

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

    如上面所示,当前数据源若没有配置事务管理器,那也是白搭!

    三. 没有被 Spring 管理 。

    //@Service
    public class OrderServiceImpl implements OrderService {
    
        @Transactional
        public void updateOrder(Order order) {
            //update order
        }
    
    }

     @Service 注掉,这个类就不会被加载成 Bean,这个类就不会被 Spring 管理了,事务自然就失效了。

    四. 方法不是 public 的(?)

     @Transactional 只能用于 public 的方法上,否则事务不会失效,如果要用在非 public 方法上,可以开启 AspectJ 代理模式。 spring的声明式事务是基于代理模式的。由于java继承时, 不能重写 private , final , static 修饰的方法。private 方法, final 方法 和 static 方法都没有事务支持。原因,pring的声明式事务是基于代理模式的。 所以, 所有的 private 方法, final 方法 和 static 方法 都无法 直接 添加spring的事务管理功能。

    private 方法无法添加事务管理. final 方法无法添加事务管理. static 方法无法添加事务管理. 当绕过代理对象, 直接调用添加事务管理的方法时, 事务管理将无法生效.?

    五. 传播类型不支持事务

    @Service
    public class OrderServiceImpl implements OrderService {
    
        @Transactional
        public void update(Order order) {
            updateOrder(order);
        }
    
        @Transactional(propagation = Propagation.NOT_SUPPORTED)
        public void updateOrder(Order order) {
            // update order
        }
    
    }

    以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。?

    六. 异常被吃了

    @Service
    public class OrderServiceImpl implements OrderService {
    
        @Transactional
        public void updateOrder(Order order) {
            try {
               
            } catch {
    
            }
        }
    }

    把异常吃了,然后又不抛出来,事务怎么回滚吧!

    七.抛出异常类型不对

    @Service
    public class OrderServiceImpl implements OrderService {
    
        @Transactional
        public void updateOrder(Order order) {
            try {
               
            } catch {
                throw new Exception("更新错误");
            }
        }
    }

    这样事务也是不生效的,因为默认回滚的是:RuntimeException。
    如果你想触发其他异常的回滚,需要在注解上配置一下,
    如:@Transactional(rollbackFor = Exception.class)
    这个配置仅限于 Throwable 异常类及其子类。

    八. 自身(this)调用问题

    @Controller
    public class TestController {
        @Autowired
        private TestService testService;
        @GetMapping("/test")
        public void test(){
    
            testService.methodA();
    
        }
        
    }
    1. 事务失效。
    因为,spring的事务实现是使用了代理类来实现,而这里的this.methodA(),并没有走TestService(被spring容器管理)的代理类,所以事务会失效。
    @Service
    public class TestService {
    
        /**
         * 这里调用methodB() 的事务将会失效
         */
        public void methodA(){
            this.methodB();
        }
        
        @Transactional
        public void methodB(){
    
        }
    }
    解决
    方法1:把methodA()和methodB()分别放到不同的类里。
    方法2:自己注入自己,用注入的实例调用。
    方法3:获取代理类,利用代理类调用自己类的方法
    方法2代码
    @Service
    public class TestService {
    
        @Autowired
        private TestService testService;
        
        /**
         * 这里调用methodB() 的事务将会生效
         */
        public void methodA(){
            testService.methodB();
        }
        @Transactional
        public void methodB(){
    
        }
    
    }
    方法3代码
    @Service
    public class TestService { /** * 这里调用methodB() 的事务将会生效 */ public void methodA(){ ((TestService)AopContext.currentProxy()).methodB(); } @Transactional public void methodB(){ } }
  • 相关阅读:
    用Sqoop进行Hive和MySQL之间的数据互导
    Spark读HBase写MySQL
    Kafka如何彻底删除topic及数据
    LDAP-HA安装与配置(Keepalived方式实现)
    配置两个Hadoop集群Kerberos认证跨域互信
    MYSQL HA 部署手册
    ELK简单安装测试
    Elasticsearch CURL命令
    大数据常见错误解决方案(转载)
    生成 RSA 公钥和私钥的方法
  • 原文地址:https://www.cnblogs.com/shijianchuzhenzhi/p/13237571.html
Copyright © 2011-2022 走看看