2

GlassFish 2.1.1 (私の知る限り、JavaEE 5、JPA 1.0) 用のアプリケーションを作成しています。サーブレットに次のコードがあります (主にインターネット上のサンプルから借用しました)。

@PersistenceContext(name = "persistence/em", unitName = "pu")
private EntityManager em;

@Resource
private UserTransaction utx;

@Override
protected void doPost(...) {
    utx.begin();
    . . . perform retrieving operations on em . . .
    utx.rollback();
}

web.xmlその中に次のものがあります。

<persistence-context-ref>
    <persistence-context-ref-name>persistence/em</persistence-context-ref-name>
    <persistence-unit-name>pu</persistence-unit-name>
</persistence-context-ref>   

問題は、em が別の外部トランザクションで行われた変更を認識しないことです。大まかに言うと、Web ブラウザからサーブレットにリクエストを送信し、データを表示し、SQL コンソールで DML を実行し、サーブレット ページをリロードしますが、何も変化がありません。em.flush、 、 、utx.rollbackの多くの組み合わせを使用しようとしましem.joinTransactionたが、効果がないようです。

私がJPAの初心者であるため、状況は複雑です。そのため、基礎となる機械がどのように機能するかを明確に理解していません。したがって、ヘルプと、さらに重要なことに、そこで何が起こっているかについての説明/リンクをいただければ幸いです。ありがとう!

4

3 に答える 3

2

JPA 実装は、アクセスされたエンティティーのキャッシュを維持します。JPA を使用せずに別のトランザクションで操作を実行すると、キャッシュが最新でなくなるため、変更が反映されません。

変更を確認したい場合は、キャッシュを更新する必要があります。この場合、すべてのエンティティがキャッシュから削除されます。もちろん、いつこれを行うべきか (他のトランザクションが完了した後) を知る必要があります。そうしないと、あいまいなエンティティが引き続き表示されます。これがビジネス ニーズである場合、JPA はおそらく問題のドメインに適していません。

関連している:

  1. エンティティはデフォルトで jpa にキャッシュされますか?
  2. JPA EntityManager セッションの無効化
于 2010-12-11T11:22:11.693 に答える
1

axtavt が言うように、コンソールでトランザクションをコミットする必要があります。それを行ったと仮定すると、データがまだ PersistenceManager (または基盤となるインフラストラクチャ) によってキャッシュされている可能性もあります。

キャッシングのトラブルを防ぐために、手動で削除するか (いつ削除するかを知る必要があるため、注意が必要です)、悲観的ロックを行うことができます。悲観的ロックはパフォーマンスに大きな影響を与える可能性がありますが、データベースへの複数の独立した接続がある場合、選択の余地がない場合があります。

プロセスが常に異なるソースからの同時読み取り/書き込みを行っている場合、悲観的ロックが本当に必要になる場合があります。外部ソースからのバッチ更新が時々ある場合は、そのバッチ ジョブから、JPA アプリケーションを削除する必要があることを知らせることができます。おそらくWebサービスなどを介して。そうすれば、悲観的なロックのパフォーマンスが常に低下することはありません。

ここでの賢明な教訓は、プロセスの同期は非常に複雑になる可能性があるということです:)

于 2010-12-11T11:27:59.637 に答える
0

おそらく、SQL コンソールで行われたトランザクションをコミットする必要があります。

于 2010-12-11T11:17:33.803 に答える