关于Spring @Configuration注解的full和lite模式导致事务没办法回滚

1.先说说在使用这个注解的时候遇到的问题吧!!!

在学习Spring transaction的时候想要实现遇到报错然后回滚,结果总是回滚失败!!最后请求大佬支援看到了我的傻逼问题

我先说说我的傻逼问题,我把@Configuration写成了@Configurable 然后在代码中使用的是:

@Configurable//这是错误的 应该改成@Configuration(proxyBeanMethod = false)
@ComponentScan("com.youshang520i")
@EnableTransactionManagement
@MapperScan("com.youshang520i.dao")
public class AppTx {

    @Bean(destroyMethod = "close")
    private DataSource dataSource(){
        BasicDataSource pool = new BasicDataSource();
        pool.setUsername("****");
        pool.setPassword("*****");
        pool.setDriverClassName("com.mysql.cj.jdbc.Driver");
        pool.setUrl("jdbc:mysql://****.***.***.***:***/test?useUnicode=true&characterEncoding=utf-8");
        return pool;
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory() throws Exception {//DataSource dataSource
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(this.dataSource());
        return sqlSessionFactoryBean.getObject();
    }

    @Bean
    public TransactionManager transactionManager(){//DataSource dataSource
        return new DataSourceTransactionManager(this.dataSource());
    }
}

2. 导致事务一直不会回滚,代码检查了很多遍配置也看了一两遍,死都不会想到我把@Configuration写成了@Configurable然后去查看源码(现在是在@Configurable注解下调试)

在源码org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction 中看到了回滚的时候这个方法被调用了两次

第一次的时候执行了TeacherService.insert,最终执行了StudentService.insert 对StudentService上的@Transactional事务进行了回滚,按照正常的来说已经实现了Spring的@Transactional的回滚

下面是StudentServiceImpl和TeacherServiceImpl的代码

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public boolean insert(StudentModel studentModel) {
//        Object savePoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint();
        int insert = 0;
        try {
            insert = studentDao.insert(studentModel);

//            insert = studentDao.insert(studentModel);

            TeacherModel teacherModel = new TeacherModel();
            teacherModel.setTid(1);
            teacherModel.setSid(studentModel.getId());
            teacherModel.setTname("m ~");
            insert = teacherService.insert(teacherModel);
        } catch (Exception e) {
//          System.out.println("发生异常,进行手动回滚!");
//            TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);
//            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            e.printStackTrace();
            throw new RuntimeException();
        }
        return insert > 0;
    }
    @Override
    @Transactional(rollbackFor = SQLException.class)//(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
    public int insert(TeacherModel teacherModel) {
        return teacherDao.insert(teacherModel);
    }

上面代码两段代码是没问题的

原因有可能是因为@Configuration(proxyBeanMethods = false)

proxyBeanMethods = false //设置lite模式

没办法保证是一个实例,在mysql触发事务回滚的时候提交的实例和回滚的实例不是同一个导致回滚失败

解决方案:

使用proxyBeanMethod = true // 设置 full模式

设置full模式可以保证创建出来的bean是在同一个实例中

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值