9

不適切な IsolationLevels を使用したデータベース接続で、アプリケーションに問題があるかどうかを把握しようとしています。私たちのアプリケーションは、SQL Server 2005 を使用する .Net 3.5 データベース アプリです。

接続が接続プールに返されたときに接続の IsolationLevel がリセットされないことを発見し (こちらを参照)、このブログ投稿で、作成された新しい TransactionScope ごとに独自の接続プールが割り当てられることを読んで本当に驚きました。

データベースの更新は (ビジネス オブジェクトを介して) TransactionScope 内で行われます (ビジネス オブジェクト グラフの更新ごとに新しいトランザクションが作成されます)。しかし、フェッチは明示的なトランザクションを使用しません。したがって、私が疑問に思っているのは、フェッチ操作 (デフォルトの IsolationLevel - Read Committed を使用する必要があります) が、更新に使用されたプールからの接続を再利用し、更新の IsolationLevel を継承するという状況に陥る可能性があるということです。 (RepeatableRead)? それとも、TransactionScope にラップされているため、更新は別の接続プールを使用することが保証されますか?

前もって感謝します、

グラハム

4

2 に答える 2

7

それは心配です!

リンク先の Bill Vaughan の記事には、「...各 TransactionScope は独自のプールを取得する」と記載されていますが、リンク先のサポート記事のコードは、それが正しくないことを示唆していますNoTxScope()。高い分離レベル。

[最初のリンクのコードを使用しています] で問題を「強制」できます。

static void ForceReadCommitedScope()
{
    TransactionOptions op = new TransactionOptions();
    op.IsolationLevel = IsolationLevel.ReadCommitted;
    using (TransactionScope tx = new TransactionScope(TransactionScopeOption.RequiresNew, op))
    {
        SqlConnection con = new SqlConnection("Data Source=.;Initial Catalog=master;Integrated Security=True;");
        SqlCommand com = new SqlCommand("select transaction_isolation_level from sys.dm_exec_sessions where (session_id = @@SPID)", con);
        con.Open();
        short level = (short)com.ExecuteScalar();
        Console.WriteLine("transaction_isolation_level : " + level.ToString());
        con.Close();
        tx.Complete();
    }
}

"..;Pooling=False"または接続文字列に追加します。

于 2010-03-15T09:02:53.773 に答える
3

SQL Server 2014では、接続がプールに返されると、プールされた接続の分離レベルがリセットされます。以前のバージョンではそうではありません。

このフォーラムの投稿を参照してください。

"SQL 2014 では、TDS バージョン 7.3 以降のクライアント ドライバーの場合、SQL サーバーは、プールされた接続のトランザクション分離レベルを既定 (読み取りコミット) にリセットします。TDS バージョン 7.3 より前のクライアントの場合、SQL に対して実行すると、古い動作になります。 2014年。

アップデート

これは、この修正により、SQL 2014 CU6 および SQL 2014 SP1 CU1 の以前の動作に再び変更されました。

修正: SQL Server 2014 で SQL Server 接続が解放されると、トランザクション分離レベルが正しくリセットされない

「SQL Server クライアント側のソース コードで TransactionScope クラスを使用し、トランザクションで SQL Server 接続を明示的に開かないと仮定します。SQL Server 接続が解放されると、トランザクション分離レベルが正しくリセットされません。」

于 2014-09-04T13:45:38.937 に答える