Forums: Open Discussion (Thread #23744)

マルチスレッドによる独自トランザクション制御 (2009-08-27 11:41 by トランザクションマン #45581)

お世話になります。

現状、ジョブ定義ファイルにPartitionNoTransactionBean.xml(トランザクション無しの分割モデル)を
使用して、独自にトランザクションを制御してクラス実装を行っています。

そこで、複数スレッドで1トランザクションで制御を行いたいと考えているのですが、うまくいきません。
※1スレッドならうまくいきます。

下記のような、記述でLogicを書いているのですが、例えばスレッドを2つ作成したとし
スレッドAが下記の、①を実行し、スレッドBが②をコミットすると同一トランザクションでも
下記のようなエラーになります。

トランザクションを開始したスレッド B が,スレッド A と同じトランザクションコンテキストで処理をするには
スレッド A で開始されたトランザクションコンテキストがだと思うのですが
それには,スレッド B でTransactionManager#resume(Transaction) を
呼び出す必要があり,その前にスレッド A でTransactionManager#suspend() を呼び出す必要があるとおもっています。

しかしながら、PlatformTransactionManagerにはresumeやsuspend処理がありません。
terasolunaで独自に複数スレッドでトランザクション処理を行うにはどうしたら良いのでしょうか。
また、TERASOLUNAで他スレッドにトランザクションコンテキストを伝播するにはどうしたら良いのでしょうか。

ご教授の程、何卒よろしくお願い致します。

※トランザクションコンテキストとはjavax.jta.Transactionを表してます。
※トランザクションの初期設定(DI)は割愛します。

●ロジッククラス
-------------------------------------------------------------------------------------------------------------
public class RealizationBLogicImpl implements BLogic<String, RealizationJobContext> {

// トランザクションDI処理は割愛します。。
protected PlatformTransactionManager transactionManager = null;
protected TransactionStatus transactionStatus;
protected DefaultTransactionDefinition def = new DefaultTransactionDefinition();
public BLogicResult execute(String voidValue, RealizationJobContext jobContext) {

  // ●①
if ("1スレッドのみ1回通過します") {
    def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
transactionStatus = transactionManager.getTransaction(def);
}



// 更新処理を何回か行う。
  updateDAO.execute(......)



  // ●②
if ("最後のスレッドだけが実行します") {
transactionManager.commit(transactionStatus);
}
-------------------------------------------------------------------------------------------------------------
●エラーコンソール

java.lang.IllegalStateException: Cannot deactivate transaction synchronization - not active
at org.springframework.transaction.support.TransactionSynchronizationManager.clearSynchronization(TransactionSynchronizationManager.java:274)
at org.springframework.transaction.support.TransactionSynchronizationManager.clear(TransactionSynchronizationManager.java:412)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.cleanupAfterCompletion(AbstractPlatformTransactionManager.java:916)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:712)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:632)
at main.java.jp.co.iij_tech.raptor.batch.condor.logic.RealizationBLogicImpl.execute(RealizationBLogicImpl.java:152)
at main.java.jp.co.iij_tech.raptor.batch.condor.logic.RealizationBLogicImpl.execute(RealizationBLogicImpl.java:1)
at jp.terasoluna.fw.batch.core.StandardBLogicExecutor.executeBLogic(StandardBLogicExecutor.java:103)
at jp.terasoluna.fw.batch.core.JobWorker.work(JobWorker.java:125)
at jp.terasoluna.fw.batch.core.JobWorker.work(JobWorker.java:67)
at jp.terasoluna.fw.batch.standard.QueueProcessor.process(QueueProcessor.java:109)
at jp.terasoluna.fw.batch.standard.RunnableQueueProcessor.run(RunnableQueueProcessor.java:98)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:417)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:269)
at java.util.concurrent.FutureTask.run(FutureTask.java:123)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)
at java.lang.Thread.run(Thread.java:595)
-------------------------------------------------------------------------------------------------------------

Reply to #45581×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Login