1

Sql Server 2008 でレプリケーションをセットアップすると、サブスクライブしているデータベースへのデータの転送を容易にするために、システムはレプリケートされたテーブルごとにトリガーを作成します。

システムによって生成されたトリガーがSET NOCOUNT ON、そのアクションが関数の値に影響を与えるのを防ぐために使用することは、予期される動作でしょう@@ROWCOUNTか?

バックグラウンド

Sql Server 2008 バックエンド データベースで NHibernate を使用しています。データベースでは、サブスクライバーへのデータ転送を容易にするために、パブリッシュされたテーブルにシステム生成トリガーを作成するレプリケーションが有効になっています。

レプリケーションがなければすべて正常に動作しますが、レプリケーションを使用すると、影響を受ける N​​Hibernate の行の検証チェックが失敗します。ADO.Net が影響を与えたと言う行数には、コマンド自体の影響を受ける行に加えて、関連するトリガーの影響を受ける行が含まれているようです。

元の質問で Sql Server 関数について言及しましたが、本当の意味は、ADO.Netメソッド@@ROWCOUNTによって返される「影響を受ける行」の値です。ExecuteNonQuery私は、後者が前者によって供給されたという仮定に (おそらく間違って) 取り組んでいたと思います。

一時的な解決策として、レプリケーション トリガーを変更して、SET NOCOUNT ON更新前に を追加し、更新が完了した後にこれを元に戻すようにしました。これで当面の問題は解決しますが、実行可能な恒久的な解決策ではありません。私たちが受け取ったアドバイスと常識によれば、システムトリガーを編集することはお勧めできません。

ただし、これは、正確な問題を特定したことを示唆しています。トリガーの影響を受ける行は、現在のコマンドの影響を受ける最終的な行数に含まれています。NHibernate は既知の数の行のみが影響を受けることを想定しており、(NHibernate に関する限り) 不明なトリガーがこの数に追加されることを想定していません。

現在、NHibernate を拡張してこれに対処する機能を追加するか、少なくともこれを抑制するオプションを調査中です。私たちのリソースには、この SO の質問が含まれています。

また、システムによって生成されたトリガーがデフォルトで NOCOUNT オプションをすでに ON に設定しているため、それらを変更する必要がないことを示唆しているように見えるこの投稿も見つけました。これは私たちには絶対に当てはまらないので、なぜそうなのかと思っていました。

  1. システム生成トリガーに関するデフォルトの状況は何ですか?
  2. 動作は構成可能ですか?
  3. レプリケーションのタイプ (マージ、トランザクション) に依存しますか?
4

1 に答える 1

1

元の質問に対する答えを特定できませんでした-(すべき/できる/方法)SQL Serverシステムで生成されたレプリケーショントリガーには、SETNOCOUNTONオプションが自動的に含まれます。

私たちのDBAチームは、答えはノーだと提案しています。彼らはまた、(かなり正しく)本番環境でシステムトリガーをカスタマイズしないと言っています。

私に開いたままのオプションは...

  1. TooManyRowsAffectedException行数の不一致が検出されたときにをスローしないようにNHibernateを変更/拡張します。
  2. NHibernateを取り除いて、ストアドプロシージャとビジネスオブジェクトへの手動マッピングに置き換えます。

オプション1を選択しました。

私の解決策は、NHibernate(2.1)コアを次のように変更することでした...

  1. 最初に、新しい動作を制御するための新しい構成オプションを追加しました。
  2. 次に、クラスのメソッドVerifyOutcomeNonBatchedVerifyOutcomeBatchedメソッドのシグネチャを変更して、新しい構成値をパラメーターとして受け入れます。NHibernate.AdoNet.Expectationsこれには、これらのメソッドが呼び出されるいくつかの場所の変更が含まれていました。
  3. TooManyRowsAffectedException最後に、これら2つのメソッドを変更して、構成オプションに従ってそれぞれがスロー/抑制するようにしました。

提案された代替実装に興味があります。

于 2010-12-10T11:21:14.100 に答える