UBTC(ユーザベーストランザクション制御) <バージョン0.3.0の概要へ戻る>

ユーザベーストランザクション制御とは、その名の通り、プログラマがトランザクションを自前で制御することを指します。
端的に言えば、プログラムコードの中で「トランザクションの開始」や「コミット」「ロールバック」を実行することを意味します。

通常、SorMapのSQLインタフェースコンテナは各インタフェースメソッド毎に一つのトランザクションが割り当てられます。

すなわち、データベースへの更新を行うDML文とリンクするupdateメソッドが存在する場合、updateメソッドを実行した瞬間に
トランザクションが開始され、updateメソッドの実行が成功した場合(何れのエラーも発生せずUPDATE文がDBで正常に実行された場合)
はコミットが自動で行われます。
もちろん、updateメソッドを実行してから終了するまでの間になんらかのエラーが発生した場合は「ロールバック」が行われ、
updateメソッドを通じて発行されたSQL文は無効化されます。
(通常のロールバックと同じです。)

このように、SorMapではデフォルトの設定でごく単純なトランザクション管理を行いますが、ケースによっては
(むしろこちらのほうが圧倒的だとは思いますが)複数のインタフェースメソッドを跨いでトランザクションを管理
したい場合もあるでしょう。

例えば、テーブルAへデータをINSERTした後に、集計データとしてテーブルBへデータをINSERTした場合などです。

また、テーブルCをサマリデータ、テーブルDをディティールデータとして、二つのテーブルにデータを登録して
初めて一つのオペレーションを成す場合です。

インタフェースメソッドでは、あくまで一つのメソッドが一つのSQL文に対応するため、上記のようなコンテナ任せのトランザクション
制御ではこのようなケースに対応できません。

上記ケースに対応するために、SorMapではトランザクションを自前でコントロールする機能が備わっております。

といっても大して特別なことではありません。

直接的には、SQLインタフェース生成時に用いたJDBCコネクションオブジェクトを使って、通常のJDBCプログラミング
で行うのと同じことをすればよいだけです。

すなわち、トランザクションを開始したい場合はsetAutoCommit(false);とし、commit();またはrollback();でトランザクションの制御を行います。

本筋は上記のとおりで、あとは通常コンテナ任せにしているトランザクション管理機能をオフにするだけです。

コンテナ任せのトランザクション管理機能を解除し、トランザクションの制御をユーザの手に取り戻すには
以下のようにしてSQLインタフェースを生成します。
  1. SampleInterface intf =
  2. SQLInterfaceFactory.newInstance().connection(con) // コネクションオブジェクトを指定
  3. .useAutoCommit(false)
  4. // 自動コミットモードオフ
  5. .useManualTransaction(true)
  6. // ユーザベーストランザクション制御オン
  7. .create(SampleInterface.class); // SQLInterfaceを生成
SQLInterfaceFactoryのuseAutoCommitメソッドおよびuseManualTransactionメソッドで
上記のようにbool値を指定すれば、コンテナ任せのトランザクション管理機能をオフにすることができます。

基本的な準備はこれだけで、あとはインタフェースメソッドを実行する前にcon#setAutoCommit(false);を実行し
処理が成功すればcon#commit();、失敗すればcon#rollback();を発行するだけです。
  1. con.setAutoCommit(true);
  2. intf.insert(new ArrayList<TestSchemeBean>());
  3. intf.update(new ArrayList<TestSchemeBean>());
  4. intf.delete(new ArrayList<TestSchemeBean>());
  5. try {
  6. con.commit();
  7. } catch (SQLException e) {
  8. try {
  9. con.rollback();
  10. } catch (SQLException e1) {
  11. e1.printStackTrace();
  12. }
  13. }
このコードはあくまでサンプルコードですので、例えばinsertメソッドに渡すBeanのリストのサイズがゼロであったり
しますが、実際には(しっかりと中身のつまった)生のデータが渡されることになります。