记一次线程中使用事务出现的问题

代码如下

getThread().execute(new Runnable() {   
    @Override
    public void run() {
        insert();
    }
});
insert(){
    insertTable1;
    insertTable2;//这是一个有唯一索引的表
}

想要的结果:当唯一索引插入报错回滚事务
问题:方法上加@Transactional(rollbackFor = Exception.class)注解并未生效
原因:
1.因为线程不属于spring托管,故线程不能够默认使用spring的事务,也不能获取spring注入的bean.
2.在被spring声明式事务管理的方法内开启多线程,多线程内的方法不被事务控制。
解决方案:
既然spring无法托管那就手动提交事务
代码如下:

getThread().execute(new Runnable() {
    @Override
    public void run() {
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        PlatformTransactionManager platformTransactionManager = SpringUtils.getBean(PlatformTransactionManager.class);
        TransactionStatus status = platformTransactionManager.getTransaction(def);
        insert();
    }
});

//SpringUtils
@Component
public class SpringUtils implements ApplicationContextAware {
    
    private static ApplicationContext applicationContext;
    
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
    
    public static  T getBean(Class tClass){
        return applicationContext.getBean(tClass);
    }
}

你可能感兴趣的:(java,线程,事务)