2012年9月4日火曜日

[AppEngine] JDO の Cross-Group-Transaction

AppEngine のデータストアでは、デフォルトではトランザクションの中で複数のエンティティグループにまたがる変更を行うことはできない。
複数のエンティティグループにまたがるトランザクションを実行するには、クロス グループ トランザクションが必要になる。今回はこのクロス グループ トランザクションを試してみる。

PersistenceManager pm = PMF.get().getPersistenceManager();
Transaction tx = null;
try {
    tx = pm.currentTransaction();
    tx.begin();
    for (int i=0; i<2; i++) {
        MyData data = new MyData();
        data.setName("one");
        pm.makePersistent(data);
    }
    tx.commit();
...

このように異なるエンティティグループの2つのオブジェクトを登録しようとすると、

Uncaught exception from servlet
javax.jdo.JDOFatalUserException: Illegal argument
   at ...
   at org.datanucleus.jdo.JDOPersistenceManager.makePersistent
   at ...

NestedThrowablesStackTrace:
java.lang.IllegalArgumentException: 
  can't operate on multiple entity groups in a single transaction.

とエラーになってしまう。
エラーは commit 時ではなく複数個の操作が発生した時に発生している。


Cross Group Trasaction


AppEngine SDK 1.5.5 からクロス グループ トランザクション(Cross Group Trasaction)、通称 XG トランザクションがサポートされている。
この機能では、最大5つのエンティティグループにまたがるトランザクションを構成できる。

App Engine Doc: datastore overview#Cross_Group_Transactions
App Engine Doc: datastore transactions

JDO で XGトランザクションを有効にするためには、src/META-INFO/jdoconfig.xml に設定を追加する。

<property name="datanucleus.appengine.datastoreEnableXGTransactions" 
          value="true"/>

先ほどの2つエンティティを作成するコードもこの設定でエラーなく動作しエンティティが2つ作成される。

上限が5つまでなのでこのコードで「 for (int i=0; i<5; i++) 」 でもエラーなくエンティティが5つ生成されるが、「 for (int i=0; i<6; i++) 」 にすると、

Uncaught exception from servlet
javax.jdo.JDOFatalUserException: Illegal argument
   at ....

NestedThrowablesStackTrace:
java.lang.IllegalArgumentException: 
   operating on too many entity groups in a single transaction.

とエンティティグループの数が多すぎるというエラーが発生する。



0 件のコメント:

コメントを投稿