美文网首页
Spring 事务失效的一种情况

Spring 事务失效的一种情况

作者: wanglei1702 | 来源:发表于2021-10-16 10:42 被阅读0次

    service 代码

    @Service
    public class UserServiceImpl implements UserService {
    
        @Autowired
        private UserMapper userMapper;
    
        @Override
        public void multiUpdateUser(User user1, User user2) {
            this.updateUser(user1);
        }
    
        @Override
        @Transactional
        public void updateUser(User user) {
            int count = userMapper.updateByPrimaryKeySelective(user);
            System.out.println(count);
            int i = 1 / 0;
        }
    }
    

    问题:controller 里面调用 multiUpdateUser() 方法,则updateUser 方法的事务失效(即使出现异常也没有回滚),事务传播行为用的默认的 REQUIRED,即支持当前事务,如果没有事务就开启事务,这里却没有开启。
    原因:
    @Transactional 注解基于AOP实现,所以 updateUser() 被其他类调用时是通过代理对象来调用的,在代理对象的增强方法中开启事务,而没有注解的 multiUpdateUser() 方法被调用是原有的对象调用的,此时在 multiUpdateUser() 方法中调用 updateUser() 方法,则 updateUser() 就是直接被原有对象调用,而没有被代理对象调用,也就不会被增强,不会开启事务,即事务失效。
    解决方案:
    手动获取 Spring 中的代理对象(即 Spring 创建的 bean),通过代理对象去调用有事务注解的方法(本例updateUser() ),首先创建工具类,通过 ApplicationContex 获取 bean

    /**
    SpringUtils 工具类
    */
    import org.springframework.beans.BeansException;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    import org.springframework.stereotype.Component;
    
    @Component
    public class SpringUtils implements ApplicationContextAware {
    
        private static ApplicationContext applicationContext;
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            if (SpringUtils.applicationContext == null) {
                SpringUtils.applicationContext = applicationContext;
            }
        }
    
        /**
         * 通过 class 获取 Bean
          */
        public static <T> T getBean(Class<T> clazz) {
            return SpringUtils.applicationContext.getBean(clazz);
        }
    }
    

    service 中的代码改造如下

    public void multiUpdateUser(User user1, User user2) {
            SpringUtils.getBean(UserService.class).updateUser(user1);
        }
    

    至此,事务就生效了。

    相关文章

      网友评论

          本文标题:Spring 事务失效的一种情况

          本文链接:https://www.haomeiwen.com/subject/ucxboltx.html