在springboot中如何保证主线程的事务和子线程的事务一致性
import cn.hutool.core.thread.NamedThreadFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
@Service
@Slf4j
public class HandleTsMoreThreadService {
@Autowired
private DataSourceTransactionManager transactionManager;
private static final ExecutorService TsMoreThreadExecutePool = new ThreadPoolExecutor(4, 64,
0L, TimeUnit.MILLISECONDS,
new SynchronousQueue<>(), new NamedThreadFactory("TsMoreThreadExecute-Pool", false),
new ThreadPoolExecutor.AbortPolicy());
public boolean executeDistributedTransaction(
Runnable mainTask,
List<Runnable> subTasks,
long timeoutSeconds) {
CountDownLatch completeLatch = new CountDownLatch(subTasks.size() + 1);
CountDownLatch commitLatch = new CountDownLatch(1);
AtomicBoolean hasError = new AtomicBoolean(false);
List<TransactionStatus> transactionStatuses = new java.util.concurrent.CopyOnWriteArrayList<>();
try {
executeMainTransaction(mainTask, completeLatch, commitLatch, hasError, transactionStatuses);
executeSubTransactions(subTasks, completeLatch, commitLatch, hasError, transactionStatuses);
boolean allCompleted = completeLatch.await(timeoutSeconds, TimeUnit.SECONDS);
if (!allCompleted) {
log.error("事务执行超时,开始回滚所有事务");
hasError.set(true);
}
if (hasError.get()) {
log.info("检测到错误,开始回滚所有事务");
rollbackAllTransactions(transactionStatuses);
return false;
} else {
log.info("所有线程执行成功,开始提交所有事务");
commitLatch.countDown();
commitAllTransactions(transactionStatuses);
return true;
}
} catch (Exception e) {
log.error("分布式事务执行异常", e);
hasError.set(true);
rollbackAllTransactions(transactionStatuses);
return false;
}
}
private void executeMainTransaction(
Runnable mainTask,
CountDownLatch completeLatch,
CountDownLatch commitLatch,
AtomicBoolean hasError,
List<TransactionStatus> transactionStatuses) {
Thread mainThread = new Thread(() -> {
TransactionStatus status = null;
try {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
status = transactionManager.getTransaction(def);
log.info("主线程事务开始执行,线程ID: {}", Thread.currentThread().getId());
mainTask.run();
log.info("主线程业务逻辑执行完成");
completeLatch.countDown();
boolean shouldCommit = commitLatch.await(300, TimeUnit.SECONDS);
if (shouldCommit && !hasError.get()) {
transactionManager.commit(status);
log.info("主线程事务提交成功");
} else {
transactionManager.rollback(status);
log.info("主线程事务回滚完成");
}
} catch (Exception e) {
log.error("主线程执行异常", e);
hasError.set(true);
completeLatch.countDown();
if (status != null && !status.isCompleted()) {
transactionManager.rollback(status);
}
} finally {
transactionStatuses.add(status);
}
});
mainThread.setName("MainTransactionThread");
mainThread.start();
}
private void executeSubTransactions(
List<Runnable> subTasks,
CountDownLatch completeLatch,
CountDownLatch commitLatch,
AtomicBoolean hasError,
List<TransactionStatus> transactionStatuses) {
for (int i = 0; i < subTasks.size(); i++) {
final int taskIndex = i;
final Runnable task = subTasks.get(i);
TsMoreThreadExecutePool.execute(() -> {
TransactionStatus status = null;
try {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
status = transactionManager.getTransaction(def);
log.info("子线程{}事务开始执行,线程ID: {}", taskIndex, Thread.currentThread().getId());
task.run();
log.info("子线程{}业务逻辑执行完成", taskIndex);
completeLatch.countDown();
boolean shouldCommit = commitLatch.await(300, TimeUnit.SECONDS);
if (shouldCommit && !hasError.get()) {
transactionManager.commit(status);
log.info("子线程{}事务提交成功", taskIndex);
} else {
transactionManager.rollback(status);
log.info("子线程{}事务回滚完成", taskIndex);
}
} catch (Exception e) {
log.error("子线程{}执行异常", taskIndex, e);
hasError.set(true);
completeLatch.countDown();
if (status != null && !status.isCompleted()) {
transactionManager.rollback(status);
}
} finally {
transactionStatuses.add(status);
}
});
}
}
private void commitAllTransactions(List<TransactionStatus> transactionStatuses) {
for (TransactionStatus status : transactionStatuses) {
try {
if (!status.isCompleted()) {
transactionManager.commit(status);
}
} catch (Exception e) {
log.error("提交事务失败", e);
}
}
}
private void rollbackAllTransactions(List<TransactionStatus> transactionStatuses) {
for (TransactionStatus status : transactionStatuses) {
try {
if (!status.isCompleted()) {
transactionManager.rollback(status);
}
} catch (Exception e) {
log.error("回滚事务失败", e);
}
}
}
public boolean executeSequentialTransaction(
Runnable mainTask,
List<Runnable> subTasks,
long timeoutSeconds) {
CountDownLatch mainTaskCompleteLatch = new CountDownLatch(1);
CountDownLatch subTasksCompleteLatch = new CountDownLatch(subTasks.size());
CountDownLatch commitLatch = new CountDownLatch(1);
AtomicBoolean hasError = new AtomicBoolean(false);
AtomicReference<TransactionStatus> mainTransactionStatus = new AtomicReference<>();
List<TransactionStatus> subTransactionStatuses = new java.util.concurrent.CopyOnWriteArrayList<>();
try {
log.info("开始执行顺序分布式事务,主事务优先执行");
executeMainTransactionSequential(
mainTask,
mainTaskCompleteLatch,
commitLatch,
hasError,
mainTransactionStatus
);
boolean mainCompleted = mainTaskCompleteLatch.await(timeoutSeconds / 2, TimeUnit.SECONDS);
if (!mainCompleted) {
log.error("主事务执行超时");
hasError.set(true);
return false;
}
if (hasError.get()) {
log.error("主事务执行失败,跳过子事务执行");
rollbackMainTransaction(mainTransactionStatus.get());
return false;
}
log.info("主事务执行完成,开始执行子事务");
executeSubTransactionsSequential(
subTasks,
subTasksCompleteLatch,
commitLatch,
hasError,
subTransactionStatuses
);
boolean subCompleted = subTasksCompleteLatch.await(timeoutSeconds / 2, TimeUnit.SECONDS);
if (!subCompleted) {
log.error("子事务执行超时");
hasError.set(true);
}
if (hasError.get()) {
log.info("检测到错误,开始回滚所有事务");
rollbackAllTransactions(mainTransactionStatus.get(), subTransactionStatuses);
return false;
} else {
log.info("所有事务执行成功,开始统一提交");
commitLatch.countDown();
commitAllTransactions(mainTransactionStatus.get(), subTransactionStatuses);
return true;
}
} catch (Exception e) {
log.error("顺序分布式事务执行异常", e);
hasError.set(true);
rollbackAllTransactions(mainTransactionStatus.get(), subTransactionStatuses);
return false;
}
}
private void executeMainTransactionSequential(
Runnable mainTask,
CountDownLatch mainTaskCompleteLatch,
CountDownLatch commitLatch,
AtomicBoolean hasError,
AtomicReference<TransactionStatus> mainTransactionStatus) {
Thread mainThread = new Thread(() -> {
TransactionStatus status = null;
try {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
def.setTimeout(300);
status = transactionManager.getTransaction(def);
log.info("主事务开始执行,线程ID: {}, 事务名称: {}",
Thread.currentThread().getId(),
Thread.currentThread().getName());
mainTask.run();
log.info("主事务业务逻辑执行完成,通知子事务开始执行");
mainTaskCompleteLatch.countDown();
boolean shouldCommit = commitLatch.await(300, TimeUnit.SECONDS);
if (shouldCommit && !hasError.get()) {
transactionManager.commit(status);
log.info("主事务提交成功");
} else {
transactionManager.rollback(status);
log.info("主事务回滚完成");
}
} catch (Exception e) {
log.error("主事务执行异常", e);
hasError.set(true);
mainTaskCompleteLatch.countDown();
if (status != null && !status.isCompleted()) {
try {
transactionManager.rollback(status);
} catch (Exception rollbackEx) {
log.error("主事务回滚异常", rollbackEx);
}
}
} finally {
mainTransactionStatus.set(status);
}
});
mainThread.setName("MainSequentialTransactionThread");
mainThread.start();
}
private void executeSubTransactionsSequential(
List<Runnable> subTasks,
CountDownLatch subTasksCompleteLatch,
CountDownLatch commitLatch,
AtomicBoolean hasError,
List<TransactionStatus> subTransactionStatuses) {
for (int i = 0; i < subTasks.size(); i++) {
final int taskIndex = i;
final Runnable task = subTasks.get(i);
TsMoreThreadExecutePool.execute(() -> {
TransactionStatus status = null;
try {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
def.setTimeout(300);
status = transactionManager.getTransaction(def);
log.info("子事务{}开始执行,线程ID: {}, 线程名称: {}",
taskIndex,
Thread.currentThread().getId(),
Thread.currentThread().getName());
task.run();
log.info("子事务{}业务逻辑执行完成", taskIndex);
subTasksCompleteLatch.countDown();
boolean shouldCommit = commitLatch.await(300, TimeUnit.SECONDS);
if (shouldCommit && !hasError.get()) {
transactionManager.commit(status);
log.info("子事务{}提交成功", taskIndex);
} else {
transactionManager.rollback(status);
log.info("子事务{}回滚完成", taskIndex);
}
} catch (Exception e) {
log.error("子事务{}执行异常", taskIndex, e);
hasError.set(true);
subTasksCompleteLatch.countDown();
if (status != null && !status.isCompleted()) {
try {
transactionManager.rollback(status);
} catch (Exception rollbackEx) {
log.error("子事务{}回滚异常", taskIndex, rollbackEx);
}
}
} finally {
subTransactionStatuses.add(status);
}
});
}
}
private void commitAllTransactions(
TransactionStatus mainStatus,
List<TransactionStatus> subStatuses) {
for (int i = 0; i < subStatuses.size(); i++) {
TransactionStatus status = subStatuses.get(i);
try {
if (status != null && !status.isCompleted()) {
transactionManager.commit(status);
log.info("子事务{}提交成功", i);
}
} catch (Exception e) {
log.error("子事务{}提交失败", i, e);
}
}
try {
if (mainStatus != null && !mainStatus.isCompleted()) {
transactionManager.commit(mainStatus);
log.info("主事务提交成功");
}
} catch (Exception e) {
log.error("主事务提交失败", e);
}
}
private void rollbackAllTransactions(
TransactionStatus mainStatus,
List<TransactionStatus> subStatuses) {
for (int i = 0; i < subStatuses.size(); i++) {
TransactionStatus status = subStatuses.get(i);
try {
if (status != null && !status.isCompleted()) {
transactionManager.rollback(status);
log.info("子事务{}回滚成功", i);
}
} catch (Exception e) {
log.error("子事务{}回滚失败", i, e);
}
}
rollbackMainTransaction(mainStatus);
}
private void rollbackMainTransaction(TransactionStatus mainStatus) {
try {
if (mainStatus != null && !mainStatus.isCompleted()) {
transactionManager.rollback(mainStatus);
log.info("主事务回滚成功");
}
} catch (Exception e) {
log.error("主事务回滚失败", e);
}
}
public void test () {
Runnable mainTask = () -> {
try {
log.info("主线程:开始保存寻源需求主表数据");
} catch (Exception e) {
log.error("主线程执行失败", e);
}
};
java.util.List<Runnable> subTasks = Arrays.asList(
() -> {
try {
log.info("执行子任务1");
} catch (Exception e) {
log.error("子线程1执行失败", e);
}
},
() -> {
try {
log.info("执行子任务2");
} catch (Exception e) {
log.error("子线程2执行失败", e);
}
}
);
boolean success = executeSequentialTransaction(
mainTask,
subTasks,
600
);
if (success) {
log.info("测试完成:所有事务提交成功");
} else {
log.error("测试完成:事务执行失败,已回滚");
}
}
}