iBatisのトランザクション制御
iBatis自身が提供するデータソースからコネクションを取得し
データベースの更新を行う場合に、同一Thread内でのコミットはSqlMapClient.commitTransaction()を
呼び出すまでコミットされない?
SqlMapClient sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader); try { sqlMap .startTransaction(); sqlMap.update (〜〜〜);・・・(A) sqlMap.insert (〜〜〜);・・・(B) sqlMap.commitTransaction(); } finally { sqlMap.endTransaction(); }
Aの後に、コネクションを取得し、Bを別にコミットさせたいとしても無理(別Threadにすればよい?ここは未調査)みたい。
(ネストしたトランザクションが無理なのか。)
SpringなどのDIコンテナ使って、Service層を別にして
それぞれでトランザクション制御(新たにコネクション取得とか、ネストしたトンらザクションを可能とか)しないと無理っぽい。
なので、iBatis提供のデータソースでRowHandlerの
public void handleRow(Object row) { }
内で、DBに対して更新をかけるような場合は、注意が必要。
Developer Guide iBATIS Data Mapper 2.0 の59ページでは
Note! トランザクションは、入れ子にできません。
同一スレッド内で、commit()やrollback()をコールする前に、
一度以上、startTransaction()をコールすると、例外がスローされます。
要するに、各スレッド内は、SqlMapClientインスタンスに対して、
一つのトランザクションだけ持つことができます。Note! SqlMapClientのトランザクションは、
JavaのThreadLocalで保持しているトランザクションオブジェクトを利用します。
これは、スレッド同士でお互い別のstartTransaction()をコールでき、
ユニークなコネクションをトランザクションで利用できることを意味しています。
とある。