私は、レポートモジュールの一部として、いくつかの長期実行SQLクエリを実行しています。これらのクエリは、実行時に動的に構築されます。ユーザーの入力に応じて、単一または複数のステートメントで、1つ以上のパラメーターを持ち、1つ以上のデータベース表で操作できます。つまり、その形式を容易に予測できません。長時間の読み取り操作にはSqlTransactionとIsolationLevelを使用しますか?
現在、私はちょうどこれらのクエリは、(実際にバッチを照会)を実行するためにしばらく時間がかかることがあるので、私は読み取り持ちこたえ表に対するロックが心配ですすなわち
using (SqlConnection cn = new SqlConnection(ConnectionString)) {
cn.Open();
// command 1
// command 2
// ...
// command N
}
、通常のSqlConnection
上でこれらのステートメントを実行しています/他のユーザーの書き込み。バッチの実行中にこれらのレポートのデータが変更されても問題はありません。レポートクエリは、それらのテーブルの他の操作より優先されるべきではなく、それらをロックする必要もありません。
データの変更を伴う、ほとんどの長期実行/複数ステートメント操作では、トランザクションを使用します。違いは、これらのレポートクエリがデータを変更していないことです。分離レベルを制御するために、これらのレポートクエリをSqlTransaction
にラップするのは正しいでしょうか?
すなわち:
using (SqlConnection cn = new SqlConnection(ConnectionString)) {
cn.Open();
using (SqlTransaction tr = cn.BeginTransaction(IsolationLevel.ReadUncommitted)) {
// command 1
// command 2
// ...
// command N
tr.Commit();
}
}
は、この私の望ましい結果を達成しますか?データが変更されていないのにトランザクションをコミットするのは正しいですか?別の方法がありますか?
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
トランザクションいじりせずに、同じ意図を実現:
レポートはhttp://blogs.msdn.com/b/sqlcat/archive/2007/02/01/previously-committed-rows-might-([正しい]である必要はありますができますbe-missed-if-nolock-hint-is-used.aspx)そうでないか? –
@RemusRusanuレポートは、長期間のデータの瞬時スナップショットを提供します。トランザクション中に発生する可能性がある変更を考慮する必要はありません。基礎となるクエリは、ユーザによって短い連続で複数回実行される可能性が高く、ユーザは結果が毎回同じであるとは期待しない。 –
これは不正な読み込みによって(ひどく)影響を受けるレポートとまったく同じです。カウントと集計はランダムに上下にジャンプし、1回の実行(レポート)内のデータは一貫性がありません(例:合計デビット!=合計クレジット)。ユーザーはランダムなデータを生成するように見えるので、レポートに対する信頼感が失われます。代わりに['SNAPSHOT'](http://msdn.microsoft.com/en-us/library/ms345124(v = sql.90).aspx)を考えましたか? –