CountDownLatch在多线程事务处理中的应用 及 单线程事务回滚机制解析
场景:
在公司接口优化的场景中,我们面临一个复杂逻辑的方法 dispatchFunction,为了提高效率,我们考虑使用 CountDownLatch
多线程处理。以下是相关代码:
@Override
public Object postDispatchtest(Map<String, Object> std_data) throws Exception {
// 获取上下文信息,供多线程使用
DWServiceContext context = DWServiceContext.getContext();
List<String> objects = new ArrayList<>();
objects.add("1");
objects.add("2");
objects.add("3");
CountDownLatch mainThreadLatch = new CountDownLatch(objects.size());
for(String a : objects){
// 使用工具类创建线程池
ThreadUtil.getInstance().execute(() -> {
try {
// 子线程获取不到上下文,需手动设置
DWServiceContext.setContext(context);
DWModuleClassLoader.setCurrentModuleName(DWServiceContext.getContext().getModuleName());
// 自己注入自己是可以实现单个子线程独立事务的
produceForMESBT.dispatchFunction(a);
}catch (Exception e){
System.out.println("报错==>>" + a);
} finally {
mainThreadLatch.countDown();
}
});
}
mainThreadLatch.await();
System.out.println("主线程要进来了");
return null;
}
@Transactional(value = "dw-transactionManager",propagation = Propagation.REQUIRED, rollbackForClassName = "Exception")
public void dispatchFunction(String a) {
String insertSql = "-${tenantsid} INSERT INTO `test1`(`title`) VALUES (?);";
dao.update(insertSql, a);
if (StringUtils.equals(a, "3")){
int b = 1/0;
}
}
这样运行后在第三次可以执行到 int b = 1/0;
这行代码的时候,会针对当前子线程发生回滚,
但是前两次插入的值不会回滚;