その中に、
<property name="javax.jdo.option.NontransactionalRead" value="true"/> <property name="javax.jdo.option.NontransactionalWrite" value="true"/> <property name="javax.jdo.option.RetainValues" value="false"/> <property name="datanucleus.appengine.autoCreateDatastoreTxns" value="true"/>
というパラメータがある。 JDO のドキュメント によると意味は以下の通り。
パラメータ | 意味 |
---|---|
NontransactionalRead | Whether to allow nontransactional reads |
NontransactionalWrite | Whether to allow nontransactional writes |
RetainValues | Whether to suppress the clearing of values from persistent instances on transaction completion |
autoCreateDatastoreTxns は JDO で規定されているパラメータではなく App Engine 固有の設定なので、 App Engine のトランザクションの説明 に記載されている。
false にすると JDO 的にトランザクションを有効にしても データストアのトランザクションは起動しないらしい。
実際に試してみよう。
NontransactionalRead/Write
このパラメータではトランザクション外でのデータの Read/Write の可否を設定する。
<property name="javax.jdo.option.NontransactionalRead" value="true"/> <property name="javax.jdo.option.NontransactionalWrite" value="true"/>
デフォルトの Read/Write=true の状態では、トランザクションが開始されていても、開始されていない場合でもRead/Writeを行うことができる。
<property name="javax.jdo.option.NontransactionalRead" value="true"/> <property name="javax.jdo.option.NontransactionalWrite" value="false"/>
NontransactionalWrite を false にした場合、トランザクションが開始されている場合には書き込みできるが、トランザクションを開始せずに書き込みをすると、
Uncaught exception from servlet org.datanucleus.jdo.exceptions.TransactionNotWritableException: Impossible to perform operation since it either requires an active transaction or 'NontransactionalRead' enabled. You have neither of these.
というエラーが発生する。今回はエンティティ作成操作を実施したので、 PersistenceManager#makePersistent を実行時にエラーが発生している。
Read操作だけならトランザクションの有無にかかわらずエラーは発生しない。
<property name="javax.jdo.option.NontransactionalRead" value="false"/> <property name="javax.jdo.option.NontransactionalWrite" value="true"/>
NontransactionalRead を false にした場合、トランザクションが開始されている場合には読み込みはできるが、トランザクションを開始せずに読み込みをすると
org.datanucleus.jdo.exceptions.TransactionNotReadableException: Impossible to perform operation since it either requires an active transaction or 'NontransactionalRead' enabled. You have neither of these.
というエラーが発生した。JDOQuery#execute でクエリーを実行する際に発生している。
Write 操作ではエラーは発生しない。
javax.jdo.option.RetainValues
この値を false にしたら コミット後に 永続化オブジェクトの値がクリアされるとのこと。
RetainValues を false にセットしてこんなコードで試してみる。
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(); resp.getWriter().println("id: " + data.getId().toString()); resp.getWriter().println("name: " + data.getName()); } finally { if ( tx != null && tx.isActive() ) { tx.rollback(); } if ( pm !=null && ! pm.isClosed()) { pm.close(); }; } -------------------- id: 31002 name: one
クリアされていなかった。こういうことじゃないのかな? 不明。
autoCreateDatastoreTxns
JDO のトランザクションを開始したときにデータストアのトランザクションを連動させるか否かを設定する。このパラメータを false に設定すると、
Transaction tx = pm.currentTransaction(); tx.begin(); for (int i=0; i<10; i++) { MyData data = new MyData(); data.setName("one"); pm.makePersistent(data); } tx.commit();
こんな風に1トランザクション中でいくつでもエンティティが作成できる。
ただし、
Transaction tx = pm.currentTransaction(); tx.begin(); for (int i=0; i<10; i++) { MyData data = new MyData(); data.setName("one"); pm.makePersistent(data); } tx.rollback();
とロールバックしてもロールバックされない。
要はコード上トランザクションを使っていても全くトランザクションが効いていない状態になっている。
もともと RDBMS で動作していた(複数のレコードをトランザクション内で操作している) JDO アプリを、無理やり App Engine で動かすためのパラメータとのことなので、通常はこれを false にすることはない。
0 件のコメント:
コメントを投稿