最近有个需求-当删除旧数据然后保存新数据时,只有删除旧数据成功同时保存新数据成功才可以不然的话就回滚,因为新数据保存那数据量比较大由子线程完成,然后删除数据是在主线程完成。

在方法上加上如下注解,看似可以其实不行,因为主线程与子线程不是同一个事务

@Transactional(rollbackFor = Exception.class)

@Transactional失效有如下场景

1.@Transactional修饰的方法为非public方法

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

  2.在类内部没有添加@Transactional的方法,调用@Transactional方法时

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

  3.在@Transactional方法内部捕获了异常,没有在catch代码块里面重新抛出异常,事务也不会回滚

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);}
}

实现代码

    @Autowiredprivate 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>() {@Overridepublic 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.ok();}

Java-主线程捕获子线程异常并回滚子线程及主线程相关推荐

  1. java主线程捕获子线程中的异常

    java主线程捕获子线程中的异常 参考文章: (1)java主线程捕获子线程中的异常 (2)https://www.cnblogs.com/jpfss/p/10272726.html (3)https ...

  2. java主线程和子线程区别_主线程异常– Java

    java主线程和子线程区别 Being a Java Programmer, you must have seen exception in thread main sometimes while r ...

  3. python主辅线程_python主线程捕获子线程的方法

    最近,在做一个项目时遇到的了一个问题,主线程无法捕获子线程中抛出的异常. 先看一个线程类的定义 ''''' Created on Oct 27, 2015 @author: wujz ''' impo ...

  4. 如何实现java主线程等待子线程执行完毕之后再执行?

    本文转自:问题:如何实现java主线程等待子线程执行完毕之后再执行? - jseven - 博客园 点击关注强哥,查看更多精彩文章呀 工作总往往会遇到异步去执行某段逻辑, 然后先处理其他事情, 处理完 ...

  5. python捕捉线程错误_python 主线程捕获子线程异常

    最近,在做一个项目时遇到的了一个问题,主线程无法捕获子线程中抛出的异常. 先看一个线程类的定义 ''' Created on Oct 27, 2015 @author: wujz ''' import ...

  6. Java主线程等待子线程、线程池

    public class TestThread extends Thread { public void run() { System.out.println(this.getName() + &qu ...

  7. java主线程控制子线程_CountDownLatch控制主线程等子线程执行完--Java多线程

    1.[代码]CountDownLatch控制主线程等子线程执行完--Java多线程 package com.sihuatech.common; import java.util.concurrent. ...

  8. java 主线程与子线程的执行顺序

    记录一个面试问题,多线程中需要等子线程全部执行完成后再执行主线程 网上的方式 1.sleep()方式,这种做法不靠谱,不知道cpu到底哪个线程会拿到,不能使用 2.将子线程加入集合中(最好是线程安全的 ...

  9. 多线程,主线程与子线程的通信Handler Message sendmessage与handlemessage obtainmessage

    android是单线程的,在子线程中是不能修改UI线程的任何操作,所以要用一种方式让子线程中的信息返回到主线程中再做修改.这就要让主线程与子线程通信. 那如何让它们之间进行通信呢?我们用Handler ...

最新文章

  1. 清理mysql创建的游戏_Linux定时清理游戏log及mysql定时任务删除游戏日志数据的步骤...
  2. RCC—使用 HSE/HIS 配置时钟
  3. php实现小说字典功能_四十章 PHP实现获取并生成数据库字典的方法
  4. 【opencv4】opencv教程 C++ 4、Mat对象(深拷贝:clone()、copyTo(),create()创建图片,zeros()、eye()初始化空白图像,Scalar()创建向量)
  5. 采用递归与栈结合的方式实现迷宫分析与走迷宫(python3)
  6. [蓝桥杯][2018年第九届真题]日志统计(树状数组)
  7. 使用有限状态机(FSM)解释shell 命令
  8. BZOJ1823[JSOI2010]满汉全席——2-SAT+tarjan缩点
  9. 《深入理解Linux内核》 读书笔记
  10. gemm() 与 gesvd() 到矩阵求逆(inverse)(根据 SVD 分解和矩阵乘法求矩阵的逆)
  11. 篮球战术谈之经典配合
  12. OpenJDK8已经将近3个月没修改了
  13. IE无法打开internet网站已终止操作的解决的方法
  14. 万有引力的意思_详细解释万有引力的本质 - 物理 - 小木虫 - 学术 科研 互动社区...
  15. P3369 普通平衡树模板 treap
  16. 研修国学请注意选好教材
  17. 正弦信号发生器设计制作经验教训
  18. ajax的blur调用,jQuery事件blur()方法的使用实例讲解
  19. python学习:爬取房源信息
  20. 机器学习系列——入门阶段(自我学习阶段的总结)

热门文章

  1. 硬盘电路板损坏故障数据如何修复?
  2. JSP/Servlet 学习笔记
  3. 面对初学者的CAN总线入门教程(三)_CAN通信中帧、优先级、位填充、错误、位时序以及同步的介绍
  4. java volatile内存屏障_从汇编看Volatile的内存屏障
  5. 华北理工大学计算机考研真题,2021华北理工大学考研历年真题
  6. 超简单解释 时间复杂度 小学生都能看懂
  7. 字节跳动自研高性能微服务框架 Kitex 的演进之旅
  8. U盘病毒mydocuments.exe查杀办法总结
  9. 10分钟让你了解应用宝APP上架流程
  10. 群晖存储服务器型号,群晖存储服务器