Java-主线程捕获子线程异常并回滚子线程及主线程
最近有个需求-当删除旧数据然后保存新数据时,只有删除旧数据成功同时保存新数据成功才可以不然的话就回滚,因为新数据保存那数据量比较大由子线程完成,然后删除数据是在主线程完成。
在方法上加上如下注解,看似可以其实不行,因为主线程与子线程不是同一个事务
@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-主线程捕获子线程异常并回滚子线程及主线程相关推荐
- java主线程捕获子线程中的异常
java主线程捕获子线程中的异常 参考文章: (1)java主线程捕获子线程中的异常 (2)https://www.cnblogs.com/jpfss/p/10272726.html (3)https ...
- java主线程和子线程区别_主线程异常– Java
java主线程和子线程区别 Being a Java Programmer, you must have seen exception in thread main sometimes while r ...
- python主辅线程_python主线程捕获子线程的方法
最近,在做一个项目时遇到的了一个问题,主线程无法捕获子线程中抛出的异常. 先看一个线程类的定义 ''''' Created on Oct 27, 2015 @author: wujz ''' impo ...
- 如何实现java主线程等待子线程执行完毕之后再执行?
本文转自:问题:如何实现java主线程等待子线程执行完毕之后再执行? - jseven - 博客园 点击关注强哥,查看更多精彩文章呀 工作总往往会遇到异步去执行某段逻辑, 然后先处理其他事情, 处理完 ...
- python捕捉线程错误_python 主线程捕获子线程异常
最近,在做一个项目时遇到的了一个问题,主线程无法捕获子线程中抛出的异常. 先看一个线程类的定义 ''' Created on Oct 27, 2015 @author: wujz ''' import ...
- Java主线程等待子线程、线程池
public class TestThread extends Thread { public void run() { System.out.println(this.getName() + &qu ...
- java主线程控制子线程_CountDownLatch控制主线程等子线程执行完--Java多线程
1.[代码]CountDownLatch控制主线程等子线程执行完--Java多线程 package com.sihuatech.common; import java.util.concurrent. ...
- java 主线程与子线程的执行顺序
记录一个面试问题,多线程中需要等子线程全部执行完成后再执行主线程 网上的方式 1.sleep()方式,这种做法不靠谱,不知道cpu到底哪个线程会拿到,不能使用 2.将子线程加入集合中(最好是线程安全的 ...
- 多线程,主线程与子线程的通信Handler Message sendmessage与handlemessage obtainmessage
android是单线程的,在子线程中是不能修改UI线程的任何操作,所以要用一种方式让子线程中的信息返回到主线程中再做修改.这就要让主线程与子线程通信. 那如何让它们之间进行通信呢?我们用Handler ...
最新文章
- 清理mysql创建的游戏_Linux定时清理游戏log及mysql定时任务删除游戏日志数据的步骤...
- RCC—使用 HSE/HIS 配置时钟
- php实现小说字典功能_四十章 PHP实现获取并生成数据库字典的方法
- 【opencv4】opencv教程 C++ 4、Mat对象(深拷贝:clone()、copyTo(),create()创建图片,zeros()、eye()初始化空白图像,Scalar()创建向量)
- 采用递归与栈结合的方式实现迷宫分析与走迷宫(python3)
- [蓝桥杯][2018年第九届真题]日志统计(树状数组)
- 使用有限状态机(FSM)解释shell 命令
- BZOJ1823[JSOI2010]满汉全席——2-SAT+tarjan缩点
- 《深入理解Linux内核》 读书笔记
- gemm() 与 gesvd() 到矩阵求逆(inverse)(根据 SVD 分解和矩阵乘法求矩阵的逆)
- 篮球战术谈之经典配合
- OpenJDK8已经将近3个月没修改了
- IE无法打开internet网站已终止操作的解决的方法
- 万有引力的意思_详细解释万有引力的本质 - 物理 - 小木虫 - 学术 科研 互动社区...
- P3369 普通平衡树模板 treap
- 研修国学请注意选好教材
- 正弦信号发生器设计制作经验教训
- ajax的blur调用,jQuery事件blur()方法的使用实例讲解
- python学习:爬取房源信息
- 机器学习系列——入门阶段(自我学习阶段的总结)