zoukankan      html  css  js  c++  java
  • 事物失效的8种情况及解决办法

    事物失效的8种情况及解决办法

    数据库引擎不支持事务

    这里以 MySQL 为例,其 MyISAM 引擎是不支持事务操作的,InnoDB 才是支持事务的引擎,一般要支持事务都会使用 InnoDB,这时候选择支持事物的数据库即可(好像是废话,哈哈哈)

    没有被 Spring 管理

    这个好像没什么可说的,脱离了Spring的管理,还谈什么Spring事物管理。

    方法不是 public 的

    @Transactional 只能用于 public 的方法上,否则事务不会失效,如果要用在非 public 方法上,可以开启 AspectJ 代理模式。

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

    相当于没开启事务管理,如果不是Springboot情况需要进行如下操作。

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

    如果是SpringBoot,在启动类上直接加上注解@EnableTransactionManagement即可。

    传播特性配错了

    传播特性配置成,Propagation.NOT_SUPPORTED或者Propagation.NOT_SUPPORTED,改成支持事物的传播特性即可。

    异常类型错误

    因为默认的异常类型是运行时异常,如果抛出了其他异常就不生效。
    解决方式:
    1、将异常改成运行时异常
    2、指定异常进行事物回滚,如:@Transactional(rollbackFor = Exception.class)

    异常被吃掉了

    如果你代码这么写,事物不生效:

        @Transactional(rollbackFor = Exception.class)
        public void updateUser2() {
         try {        
         int r1 = userInfoDAO.updateUserName(1,"3");
            int r2 = userInfoDAO.updateUserName(2,"4");
            if (r2==1){
                throw new RuntimeException();
            }
            
            }catch (Exception e){
    
            }
        }

     

    解决办法: 必须要抛出异常,否则Spring事务管理,不会走到回滚逻辑

    类内部调用

     

    @Service
    public class UserInfoService {
        public void justUpdate(){
            updateUser2();
        }
        @Transactional(rollbackFor = Exception.class)
        public void updateUser2() {
    
        }
    }

     

    上述代码不生效,因为内部调用不会涉及到代理类的调用,更不会有AOP的增强,因此不会生效。
    解决办法:
    1、自注入

    @Service
    public class UserInfoService {
       @Autowired
        private UserInfoService userInfoService;
        public void justUpdate(){
            userInfoService.updateUser2();
        }
        @Transactional(rollbackFor = Exception.class)
        public void updateUser2() {
    
        }
    }

     

    2、Spring上下文

    @Service
    public class UserInfoService {
        ApplicationContext applicationContext;
        public void justUpdate(){
               UserInfoService userInfoService = (UserInfoService) applicationContext.getBean("userInfoService");
            userInfoService.updateUser2();
        }
        @Transactional(rollbackFor = Exception.class)
        public void updateUser2() {
        }
    }

     

    3、获取他的代理类,直接调用代理类

     

    @Service
    public class UserInfoService {
        public void justUpdate(){
               ((UserInfoService) AopContext.currentProxy()).updateUser2();
        }
        @Transactional(rollbackFor = Exception.class)
        public void updateUser2() {
        }
    }

     

    因为相信,所以看见.
  • 相关阅读:
    立方体
    file 图片预览
    [LeetCode][JavaScript]Single Number III
    [LeetCode][JavaScript]Longest Substring Without Repeating Characters
    [LeetCode][JavaScript]Missing Number
    [LeetCode][JavaScript]Course Schedule II
    [LeetCode][JavaScript]Course Schedule
    [LeetCode][JavaScript]Ugly Number II
    [LeetCode][JavaScript]Ugly Number
    [LeetCode][JavaScript]Single Number II
  • 原文地址:https://www.cnblogs.com/zeenzhou/p/15219794.html
Copyright © 2011-2022 走看看