2012年

6月

13日

【Compiere Lab】モデルクラス内でのトランザクション処理の実装

  Compiere(コンピエール)のモデルクラスは、通常DBテーブル1つにつき1組作成されます(テーブル名の頭に"X_"がつくXクラスと、そのXクラスを継承して作成される、頭文字がMから始まるMクラスの1組)。モデルクラスは担当する1テーブルのデータ取得、登録、更新、削除の責任を負います。モデルクラスがその担当しているテーブルのデータを追加・更新する際には、beforSave()メソッドとafterSave()メソッドが呼び出され、そのメソッドの中にチェックロジックなどを実装できるようになっています。

 

  モデルクラスが担当しているテーブルのデータを追加・更新する分には、トランザクション処理の必要は無いのですが、場合によっては担当しているテーブルのデータを追加・更新しながら、他のテーブルのデータを更新する必要がある時もあります。そのような場合には、トランザクション処理を行う事ができます。

 

  モデルクラス内でのトランザクション処理を実装するために、私は下記のようなメンバーをクラスに追加しています。

 /** transaction   */
 private Trx   m_trx = null;

 

private void transactionStart()
{

    String trxName= get_TrxName();
   if(trxName==null)
   {
      m_trx = Trx.get(Trx.createTrxName("MassetBook"), true);
      set_TrxName(m_trx.getTrxName());
    }
}
 
private void transactionRollback()
{
   if(m_trx!=null)
   {
      m_trx.rollback();
      m_trx = null;
      set_TrxName(null);
   }
}
 
private void transactionCommit()
{
   if(m_trx!=null)
   {
      m_trx.commit();
      m_trx = null;
      set_TrxName(null);
   }

}

 このメンバーを使用して、beforSave()メソッドのretrun文の直前でtransactionStart()メソッドを実行し、afterSave()メソッドのreturn文の直前で、transactionRollback()かtransactionCommit()メソッドを実行するのを基本としています。

  transactionStart()メソッドのif文の判定は、トランザクション処理を行うかどうかを判定しています。get_TrxName()メソッドで、Stringのインスタンスが返ってくる場合は、プロセスなどによりトランザクション処理が行われているので、ここで再度トランザクション処理を行う必要はありません。

 

 transactinoRollback()とtransactionCommit()でのif文の判定は、Mクラス内でキックしたトランザクション処理かどうかを判定しています。Mクラス内でキックしたトランザクション以外はコミットもしくはロールバックしないようにするための判定文です。

 

 今のところ、この実装で特に不具合はありません。ご参考まで。