Springマルチスレッドトランザクションがロールバックする方法の実装
Springでは、@Transactionalアノテーションを使用することで、マルチスレッドでのトランザクションのロールバックを実現できます。以下はその実装方法の1つです。
- Springトランザクションマネージャ(PlatformTransactionManagerの実装クラスのDataSourceTransactionManagerなど)を設定します。
- トランザクション処理が必要なメソッドに@Transactionalアノテーションを付与する事で、そのメソッドがトランザクション処理対象となることを示します。
- 並行処理が必要な箇所で、複数のスレッドを作成して起動する。
- 各スレッドでは、トランザクション中で実行されるコードを実行するために TransactionTemplate を使用します。TransactionTemplate は、execute メソッドを提供し、これはトランザクション内で実行されるロジックを定義する TransactionCallback オブジェクトを受け取ります。
- いずれかのスレッドで例外が発生した場合、TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()でトランザクションをロールバック対象にマークできます。メインスレッドで全スレッドのトランザクションステータスを確認し、必要に応じてロールバック処理を行います。
サンプルコードを以下に示します。
@Service
public class MyService {
@Autowired
private PlatformTransactionManager transactionManager;
@Transactional
public void concurrentOperation() {
// 创建多个线程
ExecutorService executorService = Executors.newFixedThreadPool(5);
List<Future<?>> futures = new ArrayList<>();
for (int i = 0; i < 5; i++) {
// 在每个线程中执行事务操作
Future<?> future = executorService.submit(() -> {
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.execute(status -> {
// 在事务中执行操作
// ...
// 如果发生异常,标记事务为回滚
if (发生异常条件) {
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
return null;
});
return null;
});
futures.add(future);
}
// 检查所有线程的事务状态
for (Future<?> future : futures) {
try {
future.get();
} catch (Exception e) {
// 回滚事务
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
}
executorService.shutdown();
}
}
上記のコードでは、concurrentOperationメソッドは@Transactionalアノテーションでトランザクション管理を行っています。各スレッドでは、TransactionTemplateを使ってトランザクションで実行すべきコードを実行しています。いずれかのスレッドで例外が発生した場合、トランザクションはロールバックとしてマークされます。メインスレッドで全スレッドのトランザクションの状態をチェックし、必要に応じてロールバックを行います。