NHibernate Flush - どのように機能しますか? 質問する

NHibernate Flush - どのように機能しますか? 質問する

NHibernate のFlush( および) がどのように動作するのか、ちょっと混乱しています。NHibernate.ISession

私のコードから、 を使用してオブジェクトを保存するとISession.Save(entity)、オブジェクトをデータベースに直接保存できるようです。

ただし、 または を使用してオブジェクトを更新してISession.SaveOrUpdate(entity)ISession.Update(entity)、データベース内のオブジェクトは更新されません。ISession.Flush更新するには を呼び出す必要があります。

オブジェクトを更新する手順は次のとおりです。

  1. データベースからオブジェクトを取得するには、ISession.Get(typeof(T), id)
  2. オブジェクトのプロパティを変更します。たとえば、myCar.Color="Green"
  3. それをデータベースにコミットするには、ISession.Update(myCar)

データベースに更新されmyCarません。ただし、後で呼び出すとISession.Flush更新されます。

いつ使用しFlush、いつ使用しない方が良いのでしょうか?

ベストアンサー1

多くの場合、NHibernate がフラッシュするタイミングを気にする必要はありません。

独自の接続を作成した場合のみ、flushを呼び出す必要があります。NHibernate はいつコミットしたかを認識しないからです。

本当に重要なのはトランザクションです。トランザクション中は他のトランザクションから分離されます。つまり、データベースから読み取るときには常に自分の変更が表示され、他の変更は表示されません (コミットされない限り)。したがって、コミットされない限り、NHibernate がデータベース内のデータを更新しても気にする必要はありません。いずれにしても、誰にも見えません。

NHibernateは、

  • コミットを呼び出す
  • クエリの前に、メモリ内の実際の状態によってフィルタリングすることを確認する
  • フラッシュを呼び出すとき

例:

using (session = factory.CreateSession())
using (session.BeginTransaction())
{
  var entity = session.Get<Entity>(2);
  entity.Name = "new name";

  // there is no update. NHibernate flushes the changes.

  session.Transaction.Commit();
  session.Close();
}

エンティティはコミット時に更新されます。NHibernate はセッションがダーティであると判断し、変更をデータベースにフラッシュします。更新して保存する必要があるのは、セッション外で変更を行った場合のみです (つまり、分離されたエンティティ、つまりセッションで認識されないエンティティの場合)。


パフォーマンスに関する注意事項:フラッシュは、データベースを更新するために必要な SQL 文を実行するだけではありません。メモリ内の変更も検索します。POCO にはダーティ フラグがないため、セッション内のすべてのオブジェクトのすべてのプロパティを第 1 レベルのキャッシュと比較する必要があります。これを頻繁に実行すると、パフォーマンスの問題が発生する可能性があります。パフォーマンスの問題を回避するために実行できる方法がいくつかあります。

  • ループ内でフラッシュしない
  • シリアル化されたオブジェクトを避ける(変更を確認するにはシリアル化が必要です)
  • 使用読み取り専用エンティティ適切な場合
  • セット可変 = false適切な場合
  • プロパティでカスタム型を使用する場合は、効率的なEqualsメソッドを実装します。
  • 何をしているのかを十分に理解した上で、自動フラッシュを慎重に無効にしてください。

おすすめ記事