1. ホーム
  2. java

[解決済み] 同期化された静的メソッドはJavaでどのように動作し、Hibernateエンティティの読み込みに使用できますか?

2022-04-16 19:50:10

質問

基本的なデータアクセスを行うためにHibernateの関数を呼び出す静的メソッドを持つutilクラスがある場合。私は、メソッドを synchronized は、スレッドセーフを確保するための正しいアプローチです。

同じDBインスタンスに複数の情報がアクセスできないようにしたい。しかし、以下のようなコードで防ぐことができるのか、今一つ自信がありません。 getObjectById は、特定のクラスから呼び出されたときに、すべてのクラスに対して呼び出されます。

public class Utils {
     public static synchronized Object getObjectById (Class objclass, Long id) {
           // call hibernate class
         Session session = new Configuration().configure().buildSessionFactory().openSession();
         Object obj = session.load(objclass, id);
         session.close();
         return obj;
     }

     // other static methods
}

解決方法は?

静的メソッドロックにsynchronizedを使用することで、以下のことが可能になります。 クラスメソッドと属性の同期化 ( インスタンスのメソッドや属性とは対照的に )

ということは、あなたの仮定は正しいのですね。

スレッドセーフを確保するために、このメソッドをsynchronizedにすることが正しいアプローチなのかどうか悩んでいます。

そうでもないですよ。その作業は、代わりにRDBMSに任せるべきです。RDBMSはこの種のことに長けています。

データベースへのアクセスを同期させることで得られるのは、アプリケーションが恐ろしく遅くなることだけです。 さらに、あなたが投稿したコードでは、毎回セッションファクトリーを構築しているので、あなたのアプリケーションは実際の仕事を実行するよりもDBにアクセスすることに多くの時間を費やすことになるのです。

次のようなシナリオを想像してください。

クライアントAとBは、テーブルTのレコードXに異なる情報を挿入しようとする。

あなたのアプローチでは、RDBMSがAからとBから同時に半分の情報を挿入することを防ぐので、DBではいずれそうなるのに、一方が他方の後に呼び出されることを確認することだけを得ています。結果は同じですが、5倍(またはそれ以上)遅くなるだけです。

おそらく、このような場合は トランザクションと同時並行性 の章をご覧ください。 ほとんどの場合、あなたが解決しようとしている問題は、すでに解決されており、より良い方法です。