3

nHibernate で競合状態が発生し、データベースに重複したエントリが作成されています。残念ながら、UNIQUEデータベースにインデックスを作成できないため、nHibernate メソッドのみを使用してこのエラーを解決したいと考えています。これは、Web ファームで実行される可能性のある Web アプリケーションです (したがって、システム ロックでも問題は解決しないはずです)。簡略化した状況は次のとおりです。

var current = UnitOfWorkManager.Instance.Current;
current.BeginTransaction(IsolationLevel.Serializable);
try {

    var myEntity = MyFactory.MyEntityRepository.GetBy(product, company);
    // race condition happens between the previous statement and Save() method.

    if (myEntity == null)
    {
      myEntity = new MyEntity();
      myEntity.Product     = product;
      myEntity.Company     = company;
      myEntity.Date        = date;
      myEntity.CurrentUser = currentUser;
      myEntity.IsManual    = true;
      myEntity.Save();
    }
    else
    {
      myEntity.IsManual    = false;
      myEntity.Save();
    }
    current.CommitTransaction();
}
catch {
    current.RollbackTransaction();
    throw;
}

私は nHibernate を初めて使用するので、ここでいくつかの基本が欠けている可能性があります。フィードバックをいただければ幸いです。:)

4

3 に答える 3

1

nHibernate マニュアルを読んだ後、問題は、subProjectToSupplier が null でない場合に保存するための 2 回目の呼び出しであると思います。nHibernate のマニュアルには、「保存」は挿入を行うと記載されているためです。

SaveOrUpdate を試す

于 2013-07-11T14:59:54.310 に答える
0

OK、ここで NHibernate ソリューションを求めています。これで問題が 100% 解決するかどうかはわかりませんが、これを試してみてください。

  1. ReadCommitted 分離レベルを使用します。
  2. 必要に応じてインターセプターを実装しますhttp://nhibernate.info/doc/nh/en/#manipulatingdata-interceptors

インターセプター内で次のことができます。

  1. 一意の列にレコードがある場合は、DB にクエリを実行します。次に、ある種のマージメカニズムを適用できます
  2. あなたのような他のオブジェクトが永続化されるのを待っている場合は、現在のセッションを確認してください。

================

他の解決策は、ファーム間で共有キャッシュ (memcache) を保持し、複製したくないオブジェクトを追跡することです。

PS: それぞれのポイントについて詳しくお話しできます。何か解決策のように思えることがあれば教えてください

于 2013-07-11T13:11:09.407 に答える