Java DAO のメソッドで 'synchronized' キーワードを使用すると、Web アプリケーションで使用すると問題が発生しますか?
ここに示すように、リソースの競合を回避するためにメソッドを同期する必要があるマルチスレッドのスタンドアロン アプリケーションがあるため、質問します。
java.util.concurrent.ExecutionException: javax.persistence.PersistenceException: org.hibernate.HibernateException: Found shared references to a collection: com.replaced.orm.jpa.Entity.stuffCollection
私が懸念しているのは、かなりの数の人がアプリケーションを使用しようとすると、同期されたメソッドがブロックされ、アプリケーション全体が遅くなることです。
DAO にエンティティ マネージャーを提供する、Spring が注入された JPA エンティティ マネージャー ファクトリを使用しています。技術的には、DAO レイヤーを削除して、クラスにエンティティ マネージャー ファクトリを直接呼び出させることもできますが、DAO が提供する分離を楽しんでいます。
また、接続されたエンティティ ORM オブジェクトをスレッド間で受け渡さないように細心の注意を払っていることにも注意してください。DAOへのアクセス時にリソース競合エラーが発生するのではないかと推測しています。複数のスレッドが同時に進行していて、非アトミックな方法でデータベースを永続化または読み取りしようとしていると思います。
この場合、DAO を使用すると、助けよりも害が大きくなりますか?
私が質問から外した重要な情報は、DAO がシングルトンではないということです。その詳細を含めるのに十分明快に考えていたなら、そもそもその質問をしなかったでしょう.
私の理解が正しければ、Spring はそれを使用するクラスごとに DAO クラスの新しいインスタンスを作成します。したがって、バッキング エンティティ マネージャーは各スレッドに固有である必要があります。Rob H が答えたように、ここで重要なことは、エンティティ マネージャーを共有しないことです。
ただし、同期を削除するとエラーが発生する理由がわかりません。
このスレッドによると、 @PersistenceContext アノテーションはスレッドセーフな SharedEntityManager を作成します。したがって、シングルトン DAO を作成できるはずです。