多线程事务管理器
package com.lf.ibms.backend.web.rest;
import cn.hutool.core.collection.CollUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
@Component
@Slf4j
public class MultiplyThreadTransactionManager {
@Resource
private PlatformTransactionManager platformTransactionManager;
public void runAsyncButRollbackAllOnException(List<Runnable> tasks) {
if (CollUtil.isEmpty(tasks)) {
throw new IllegalArgumentException("任务列表不能为空。");
}
AtomicBoolean isError = new AtomicBoolean(false);
TransactionStatus mainTransaction = platformTransactionManager.getTransaction(new DefaultTransactionDefinition());
try {
for (Runnable task : tasks) {
TransactionStatus subThreadTransaction = platformTransactionManager.getTransaction(new DefaultTransactionDefinition());
try {
task.run();
platformTransactionManager.commit(subThreadTransaction);
} catch (Exception e) {
isError.set(true);
platformTransactionManager.rollback(subThreadTransaction);
log.error("任务发生错误:{}", e.getMessage(), e);
break;
}
}
if (isError.get()) {
platformTransactionManager.rollback(mainTransaction);
log.warn("某个子线程发生异常!主事务回滚!");
} else {
platformTransactionManager.commit(mainTransaction);
log.info("所有事务正常提交!");
}
} catch (Exception e) {
platformTransactionManager.rollback(mainTransaction);
log.error("主线程出现异常:{}", e.getMessage(), e);
}
}
}
测试
@GetMapping(value = "/testMultiThreadTransactional")
public void testMultiThreadTransactional(String param) {
List<Runnable> tasks = new ArrayList<>();
tasks.add(() -> {
recordUploadFileMapper.deleteByPrimaryKey(250L);
if ("abc".equals(param)) {
throw new RuntimeException("抛出异常!");
}
});
tasks.add(() -> recordUploadFileMapper.deleteByPrimaryKey(251L));
multiplyThreadTransactionManager.runAsyncButRollbackAllOnException(tasks);
}