6

Hibernateおよび/または永続性に関連する可能性のある問題に対してテストプルーフしたいアプリケーションがあります。

他にどのような問題がありますか?それらを(文字通り)どのように再現しますか?そして、どのようにそれらから回復しますか?

明確にするために:私はマルチスレッドクラスター環境(最も複雑な環境)について話しています。

私のもの:

org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)

再現:

  • オブジェクトをロードします。
  • HQLを使用して更新します。
  • ロードされたオブジェクトを更新(保存)してみてください。

ハンドル:わからない...

4

3 に答える 3

8

遅延読み込みは、特に標準の DAO パターンに従っている場合に発生する大きな問題の 1 つです。遅延ロードされたコレクションになってしまいますが、DAO レイヤーから出ると、春 (または春を使用していない場合は他の何か) がセッションを閉じる可能性があります。

public class MyDaoImpl implements MyDao {
   @Override
   @Transactional
   public void save(MyObject object) { ... }
}

この場合、「保存」の呼び出しが完了すると、別のトランザクション内にいない場合、Spring はセッションを閉じます。その結果、遅延ロードされたオブジェクトを呼び出すと、LazyInitializationException がスローされます。

これを処理する一般的な方法は、セッションを現在のスレッドにバインドすることです。Web アプリケーションでは、OpenSessionInViewFilter を使用してこれを簡単に行うことができます。コマンド ラインの場合は、おそらく、セッションを作成し、現在のスレッドにバインドし、完了したらバインドを解除するユーティリティ メソッドを記述する必要があります。この例は、ウェブ全体で見つけることができます。

また、コレクションに関しては、「更新」メソッドを使用する場合 (これも標準の DAO パターンで通常行うことです)、コレクション インスタンスを置き換えないように注意する必要がありますが、既に存在するコレクションを操作する必要があります。所定の位置に。そうしないと、休止状態は、追加/削除/更新する必要があるものを理解するのに苦労します。

于 2012-07-02T18:17:03.927 に答える
2

あなたが観察した問題は、データの同時変更の 1 つです。Hibernate には、これに対処するための多くの解決策があります。

基本的に、問題は 2 つのスレッド (またはクラスター内の 2 つのマシン) が同じデータに対して同時に動作していることです。次の例を検討してください。

machine 1: reads the data and returns it for editing somewhere else
machine 2: also reads the data for modification
machine 1: updates the data and commits.
machine 2: tries to do an update and commit.

2 番目のマシンがその変更をコミットしようとするとどうなりますか? Hibernate は、マシン 2 がデータを処理している間にデータが変更されたことを確認します。つまり、マシン 2 の更新は古いデータに基づいています。Hibernate は常に 2 つの変更をマージできるわけではありません (また、常に望ましい動作でもありません)。org.hibernate.StaleObjectStateException

上で述べたように、Hibernate はこの問題を解決するための多くのオプションを提供します。@Versionおそらく最も簡単なのは、データ オブジェクトを使用してバージョン フィールドを追加することです。Hibernate は、データの「バージョン」を自動的に維持します。更新が行われるたびに、バージョンは Hibernate によって自動的に変更されます。あなたの仕事は、データを読んでからデータを更新するまでの間にバージョンが変わっていないことを確認することです。それらが一致しない場合は、問題を処理するために何かを行うことができます (つまり、ユーザーに伝えます)。同時更新を防止するためのより洗練された手法がいくつかありますが、これが最も簡単です。

于 2012-07-02T17:53:48.143 に答える
1

あまりにも多くのデータを取得することは、おそらく ORM ツールを使用するときに発生する可能性がある最大の問題です。これは、必要以上に多くのデータを簡単にロードできるためです。テスト データの量がかなり少ない場合、この問題は開発/テスト シナリオでは再現されず、データが本番環境に蓄積され始めると、データ アクセス レイヤーが指数関数的に遅くなる可能性があります。

発生する可能性のある多くの問題があります。

  • バッチ更新の欠如
  • ステートメントキャッシングの欠如
  • ロックしすぎ
  • データベースのラウンドトリップが多すぎる
  • 非効率的な SQL ステートメントを生成するエキゾチックな関連付け
于 2016-04-06T10:06:53.137 に答える