- 使用编程式事务手动管理多线程事务的生命周期,通过原子类 + CountDown去控制多线程事务的全局提交或回滚
public class ThreadTransactionUtil {
private DataSourceTransactionManager transactionManager;
private final List<Handle> handleList = new ArrayList<>();
private int isolationLevel = TransactionDefinition.ISOLATION_DEFAULT;
private int propagationBehavior = TransactionDefinition.PROPAGATION_REQUIRED;
public static void main(String[] args) {
Object o = new Object();
boolean isCommit = ThreadTransactionUtil.builder().add(o::toString).add(o::toString).begin();
}
public static ThreadTransactionUtil builder() {
ThreadTransactionUtil util = new ThreadTransactionUtil();
util.transactionManager = SpringUtils.getBean(DataSourceTransactionManager.class);
return util;
}
public ThreadTransactionUtil add(Handle s) {
handleList.add(s);
return this;
}
public boolean begin() {
AtomicBoolean isCommit = new AtomicBoolean(true);
CountDownLatch cd = new CountDownLatch(handleList.size());
handleList.forEach(l -> CompletableFuture.runAsync(() -> {
TransactionStatus ts = beginTransaction();
try {
l.handle();
} catch (Exception e) {
isCommit.set(false);
log.error("线程事务出现异常",e);
}
cd.countDown();
while (cd.getCount() > 0 && isCommit.get()) {
sleep(50);
}
if (isCommit.get()) {
transactionManager.commit(ts);
} else {
transactionManager.rollback(ts);
}
}));
try {
cd.await();
} catch (InterruptedException e) {
e.printStackTrace();
throw new RuntimeException("多线程事务线程等待出现异常");
}
return isCommit.get();
}
public ThreadTransactionUtil isolationLevel(int isolationLevel) {
this.isolationLevel = isolationLevel;
return this;
}
public ThreadTransactionUtil propagationBehavior(int propagationBehavior) {
this.propagationBehavior = propagationBehavior;
return this;
}
private TransactionStatus beginTransaction() {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setIsolationLevel(isolationLevel);
def.setPropagationBehavior(propagationBehavior);
return transactionManager.getTransaction(def);
}
private void sleep(long mill) {
try {
Thread.sleep(mill);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
public interface Handle {
void handle();
}
}