资讯详情

Java-主线程捕获子线程异常并回滚子线程及主线程

最近有一个需求——当删除旧数据并保存新数据时,只有成功删除旧数据并保存新数据才能回滚,因为新数据保存的数据量相对较大,然后在主线程中删除数据。

在方法上加上以下注释,似乎不可能,因为主线程和子线程不是同一个事务

@Transactional(rollbackFor = Exception.class)

@Transactional故障如下

1.

是基于动态代理来实现的,非public的方法,动态代理对象信息为空,不能回滚。

@Transactional它是基于动态代理对象实现的,类内部方法的调用是通过this关键词没有动态代理对象,所以事务回滚无效。

4.方法用final或static修饰

若某种方法使用final修改后,在其代理类别中,不能重写该方法并添加事务功能。

5.未被spring管理

通常,我们通过@Controller、@Service、@Component、@Repository等待注释,可自动实现bean实例化和依赖注入功能。

6.事务始事务

7.多线程调用

同一事务实际上是指同一数据库连接,只有同一数据库连接才能同时提交和回滚。

8.表格不支持事务

查看数据库引擎

创建事务管理器

@Component public class txManagerConfig {     // 创建事务管理器     @Bean(name = "txManager")     public PlatformTransactionManager txManager(DataSource dataSource) {         return new DataSourceTransactionManager(dataSource);     } }

现代

    @Autowired     private PlatformTransactionManager txManager;      private boolean isExec = false;      @Override     @Transactional(rollbackFor = Exception.class)     public R save(List<XXXDataDTO> params) {         if (params == null || params.isEmpty()) {             return R.error("没有数据,保存失败!");         }         try {             ///判断该条记录的旧数据是否被删除             ...             //开启线程,保存新数据             Callable<Object> callable = new Callable<Object>() {                 @Override                 public Object call() throws Exception {                     DefaultTransactionDefinition def = new DefaultTransactionDefinition();                     def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);                     TransactionStatus status = txManager.getTransaction(def);                     try {                         ///新数据保存                      ...                         // 提交事务                         txManager.commit(status);                     } catch (Exception e) {                         // 回滚事务                         txManager.rollback(status);                         throw new RuntimeException();                     }                     return "success";                 }             };             FutureTask<Object> futureTask = new FutureTask<Object>(callable);             thread = new Thread(futureTask);             thread.start();             System.out.println(futureTask.get());         } catch (Exception e) {             e.printStackTrace();             isExec = true;             throw new RuntimeException("xxx保存失败!");         } finally {             if (thread.isAlive()) {                 thread.interrupt();             }         }         return isExec ? R.error("保存失败! R.error("保存失败!") : R.ok();     }

标签: 连接器主线

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台