休止状態を使用していくつかのデータベース挿入操作が行われている方法があり、それらをスレッドセーフにしたいと考えています。このメソッドはパラメーターでいくつかのデータを取得しており、同じ時点で同じデータを使用して 2 つの呼び出しが行われる可能性があります。
パフォーマンスが低下しているため、これらのテーブルをロックできません。メソッドを同期化することで問題が解決することを提案できる人はいますか?
休止状態を使用していくつかのデータベース挿入操作が行われている方法があり、それらをスレッドセーフにしたいと考えています。このメソッドはパラメーターでいくつかのデータを取得しており、同じ時点で同じデータを使用して 2 つの呼び出しが行われる可能性があります。
パフォーマンスが低下しているため、これらのテーブルをロックできません。メソッドを同期化することで問題が解決することを提案できる人はいますか?
メソッドを同期すると、一度に 1 つのスレッドのみがアクセスできるようになります。この方法がデータベースへの書き込みの唯一の手段である場合、はい、これにより、2 つのスレッドが同時に書き込むことができなくなります。ただし、同じデータに対して複数の挿入操作があるという事実に対処する必要があります。
Hibernateに並行性を処理させる必要があります。これは、Hibernateが行うことを意図したものです。Hibernateが何かをロックするとは思わないでください。まさにこの目的のために楽観的なトランザクションをサポートします。上記のリンクからの引用:
高い同時実行性と高いスケーラビリティと一致する唯一のアプローチは、バージョン管理による楽観的同時実行制御です。バージョンチェックでは、バージョン番号またはタイムスタンプを使用して、競合する更新を検出し、更新の損失を防ぎます。Hibernateは、楽観的並行性を使用するアプリケーションコードを記述するための3つの可能なアプローチを提供します。
データベースの同時実行性は、トランザクションによって処理されます。トランザクションには、Atomic Consistent Isolated Durable (ACID) プロパティがあります。これらは、データベースに同時にアクセスするプログラム間の分離を提供します。Spring フレームワークの Hibernate DAO テンプレートには、データベースに対する CRUD 操作のための単一行メソッドがあります。個別に使用する場合、これらをメソッドで同期する必要はありません。Spring は、特定の伝播設定、rollbackFor 設定、分離設定を使用して「メソッド」をトランザクションとして宣言する必要がある場合、宣言型 (XML)、プログラムおよび注釈のメタデータ駆動型トランザクション管理を提供します。したがって、「あなたのメソッド」では、複数の保存、更新、削除などを行うことができ、ORM は、メタデータで指定したトランザクション設定で確実に実行されます。
もう 1 つの問題は、トランザクションに参加しているすべてのオブジェクトをスレッドがロックする必要があることです。そうしないと、トランザクションが失敗するか、ORM が古いデータを保持します。別の状況では、ロック順序が原因でデッドロックが発生する可能性があります。これが本当にあなたの質問に答えるものだと思います。
オブジェクト a と b の両方に Lock 型のインスタンス変数があります。ブール値フラグを使用して、トランザクションの成功を示すことができます。クライアント コードは、失敗した場合に同じトランザクションを再試行できます。
if (a.lock.tryLock()) {
try {
if (b.lock.tryLock()) {
try {
// persist or update object a and b
} finally {
b.lock.unlock();
}
}
} finally {
a.lock.unlock();
}
}
同期メソッドを使用する際の問題は、Service または DAO クラス全体がロックされ、他のサービス メソッドが他のスレッドで使用できなくなることです。オブジェクトに個別のロックを使用することで、細粒度の同時実行の利点を得ることができます。
いいえ。このメソッドはおそらく別のメソッドとオブジェクトを使用しますが、スレッドセーフではない可能性があります。synchronized
スレッドがそのメソッドのオブジェクトをmonitor
一度に1回だけ使用するようにするため、オブジェクトに関してスレッドセーフなメソッドになります。
他のすべてのスレッドがこのメソッドでのみ共有機能を使用することが確実な場合は、それを作成するだけでsynchronized
十分な場合があります。
最適な戦略の選択はアーキテクチャに依存します。パフォーマンスを向上させるには、メソッド同期のようなトリックを使用する方が簡単な場合もありますが、これは悪いアプローチです。
疑いの余地はありません。トランザクションを使用する必要があります。その戦略でパフォーマンスの問題に直面している場合は、db クエリまたは db 構造を最適化する必要があります。
「同期」は可能な限りアトミックに行う必要があることに注意してください。