[Seasar-user:3221] Re: トランザクションの制御について

Koichi Kobayashi koichik
2006年 2月 18日 (土) 03:04:01 JST


小林 (koichik) です.

Date:    Sat, 18 Feb 2006 02:19:37 +0900
From:    "J.r0ck" <[E-MAIL ADDRESS DELETED]>
To:      [E-MAIL ADDRESS DELETED]
Subject: [Seasar-user:3220] Re: トランザクションの制御について

> S2のトランザクションってXA(分散トランザクション)でもって
> XAResourceが複数あれば、きちんと2フェーズコミットする本格的な
> JTAですよね。

トランザクションログは作成しませんが,必要ならきちんと
2 フェーズコミットします.

> だから...
> 1.トランザクション開始
> 2.Aスレッドで更新処理(セッション1)
> 3.Bスレッドで更新処理(セッション2)
> 4.Cスレッドで更新処理(セッション3)
> 5.すべてのスレッド終了待ち
> 6.コミット
> ってなことが出来ると思ってたんですが?

JTA 仕様では必須ではありませんが,S2JTA としては可能です.

ただし.
同一のトランザクションに属する処理を複数のスレッドに
またがって処理するには,トランザクションコンテキストつまり
javax.jta.Transaction をスレッドに伝播する必要があります.
上の場合,トランザクションを開始したスレッドが A であるとして,
スレッド B が同じトランザクションコンテキストで処理をするには
スレッド A で開始されたトランザクションコンテキストが必要です.

それには,スレッド B でTransactionManager#resume(Transaction) を
呼び出す必要があり,その前にスレッド A で
TransactionManager#suspend() を呼び出す必要があります.
suspend していない Transaction を resume することはできません.

結局,スレッド A とスレッド B,さらにスレッド C で同じ
Transaction が同時にアクティブになることはありません.
そして S2DBCP は,一つの Transaction の元では常に同じ
Connection を返します.

よって,上記のような処理は不可能ではありませんが,
各スレッドが同時に DB にアクセスできるわけではありません.

JTA 仕様ではネストした Transaction をサポートすることが
許されています.
そのような JTA 実装の場合には,スレッドことに個別の
ネステッドトランザクションをアクティブにすることが
可能だと思われますが,S2JTA ではサポートしていません.

もしネステッドトランザクションをサポートした JTA 実装が
あったとしても (ありますけど) その効果は微妙.
例えば Oracle では同一のグローバルトランザクションに属する
コネクション (セッション) で同時に実行可能な SQL は
一つだけです.
複数のスレッドから個別の XAConnection で同時に SQL を
発行しても,それらが同じグローバルトランザクションに
属しているなら Oracle によって同期的 (逐次) に実行されます.

> > S2DBCP は一つのトランザクションの元では常に同じ
> > JDBC コネクションを返します (論理・物理とも).
> 上記の例の場合、コミットする時は1つのコネクションだけになるのでしょうか?

はい.

> Oracleの一時表がうまく使えるかどうかは
> セッションローカルなトランザクションではなく
> XAトランザクションであるがため...との認識だったんですが
> これ間違いなのかしら?

設定に問題があったようですね.

> もしくは、根本的にS2のトランザクションに関して、思い切り
> 思い違いをしてるかもしれないのでご意見お願いいたします。

S2 のというか,そもそも 2 フェーズコミットというのは
複数のリソースマネージャ (DBMS とか) を使用する場合に
必要となるものです.
Oracle と SQL-Server とか,Oracle と ActiveMQ とか.
複数のスレッドにまたがっていても,一つのリソースしか
使わないのであれば,2 フェーズコミットは必要ありません.

リモートの EJB など,複数のノードから同一の
トランザクション下でリソースマネージャを利用する場合は
グローバルトランザクションが必要になりますが,その場合でも
当該トランザクションに参加しているリソースが一つだけなら
2 フェーズコミットは不要です.


-- 
<signature>
    <name>Koichi Kobayashi</name>
    <e-mail>[E-MAIL ADDRESS DELETED]</e-mail>
</signature>




Seasar-user メーリングリストの案内