6

データベースが破損しないように Hibernate のトランザクションがどのように機能するかについての情報を見つけることができましたが、Hibernate がスレッド間で共有されるオブジェクトをどのように処理し、各スレッドがそれをデータベースに保存しようとするかを理解することは困難でした。

これは私の理論的な質問です:

1) 属性 (ssn、名前、住所) を持つ Person オブジェクトがあります。2) 3 つのスレッドがこの人物オブジェクトへの参照を持ち、各スレッドがメソッド savePersonToHibernate(...) を呼び出します。

public void savePersonToHibernate(Person person)
{
...
session.saveOrUpdate(person)
...
}

Hibernate は、同じオブジェクトをストレージに書き込む 3 つのスレッドにどのように対処しますか? すべてのトランザクションをキューに入れるので、最初のスレッドが行と識別子を作成 (ID を設定) すると、残りの 2 つのスレッドは (この場合) 変更なしでのみ更新しますか? または、実際にデータベースに 2 つまたは 3 つの行があり、現在のオブジェクトが最後に作成された識別子のみを参照している可能性はありますか?

ちょっと意味があることを願っています...私はキューシステムを作成しています.データは、その場で作成する必要があるカテゴリに参照する必要があります...そして、2つ以上のスレッドが両方が必要とするデータを取得する場合同じカテゴリを作成するために、重複したくありません。

これが理にかなっているといいのですが...どうしますか?

4

1 に答える 1

4

上記のすべてのスレッドが異なるセッションを使用すると仮定しています。そうしないと、休止状態セッションがスレッドセーフではないため、問題が発生します。

明確にするために、3 つのスレッドすべてが person の同じインスタンスを使用していて、これが新しいオブジェクトである場合、オブジェクトへのアクセスまたは変更時に休止状態が同期を行わないため、問題が発生します。基本的に、各スレッドは他のスレッドが存在しないかのように動作するため、まず person の ID が null でないかどうかを確認し、id が null の場合は生成を試みてから、適切なエンティティ フィールドに割り当てます。異なるスレッドでの check-generate-assign のタイミングと変更の可視性の影響によっては、同時作成の結果は予測できません。

すべてのスレッドが person の異なるインスタンスを使用しているが、同じ属性値を使用している場合にどうなるか見てみましょう。この場合、各スレッドはデータベースに 3 つの異なる行を作成しようとします。基になるテーブルに一意の制約 (一意の名前など) がなければ、成功します。

カテゴリを作成する特定のシナリオは、実装が簡単ではありません。アイデアは、カテゴリを作成しようとすることですが、既に存在する場合は例外をキャッチします。後者の場合、データベースから既存のカテゴリを読み取り、それを使用します。ただし、条件付き挿入の実装は簡単ではなく、RDBMS に依存する可能性があることに注意してください。PostgreSQLおよびSQL Serverの upsert 操作については、もう少し複雑ですが関連する例を参照してください。

于 2013-10-23T22:33:57.097 に答える