2012年9月3日月曜日

[AppEngine] JDO のトランザクション

JDOでのトランザクションの基本。

PersistenceManager pm = PMF.get().getPersistenceManager();
Transaction tx = null;
try {
    tx = pm.currentTransaction();
    tx.begin();
    MyData data = new MyData();
    data.setName("one");
    pm.makePersistent(data);
    tx.commit();
} finally {
    if ( tx != null && tx.isActive() ) {
        tx.rollback();
    }
    if ( pm !=null && ! pm.isClosed()) {
        pm.close();
    };
}

PersistenceManager#currentTransaction で Transaction オブジェクトを取得して、 Transaction#begin でトランザクション開始。
Transaction#commit() でコミット、Transaction#rollback でロールバック。

本当は、rollback 時にも PersistenceManager がクローズされるようにもう一段 try...finally が 必要だけどここは手抜き。

エラー時にロールバックをきちんとしないでトランザクションが Active なまま PersistenceManager をクローズすると、

javax.jdo.JDOUserException: Transaction is still active. 
You should always close your transactions correctly using commit() or rollback().
FailedObject:org.datanucleus.store.appengine.jdo.DatastoreJDOPersistenceManager@9db0e2
 at org.datanucleus.jdo.JDOPersistenceManager.close(JDOPersistenceManager.java:277)

というエラーになる。
最終的には、

com.google.apphosting.utils.servlet.TransactionCleanupFilter handleAbandonedTxns: 
Request completed without committing or rolling back transaction with id -7895842753490378.  Transaction will be rolled back.

と、TransactionCleanupFilter によってロールバックが実行されるようだ。

0 件のコメント:

コメントを投稿