2

Pieter De Rycke による次の優れた記事を読みました。

http://pieterderycke.wordpress.com/2012/01/22/transactionscope-transaction-escalation-behavior/

SQL Server 2012 でのトランザクション エスカレーション動作に関するドキュメントをインターネットで検索しようとしましたが、成功しませんでした。

SQL Server 2012 の動作が SQL2008 と異なるかどうかは誰にもわかりませんか? 現在、TransactionScope と DTC への昇格に問題があります (これは望ましくありません)。

4

2 に答える 2

2

SQL Server 2012 (EXPRESS) で分散トランザクションへのエスカレーションがどのように動作するかを試しました。また、SQL Server 2008 と同じ動作を確認しました。

オブジェクトを使用した非常に単純なコードでテストしましたSqlConnection。1 つのトランザクション スコープには、常に 2 つのデータベース アクセス (INSERT) があります。

ネストされていない接続 - エスカレートしない

これは、DTC への昇格を回避したい場合の唯一のオプションです。トランザクション中に 1 つの永続的なリソース (データベース) にのみアクセスし、1 つの接続を閉じてから別の接続を開きます。(最終的には、同じ接続を再利用することで DT を回避できますが、接続プールを使用する場合は必要なく、コードが読みにくくなる可能性があります。)

static string connectionString = "data source=.\\;Integrated Security=SSPI;Database=TestDB";

static void Main(string[] args)
{
    using (var scope = new TransactionScope())
    {
        using (var conn = new SqlConnection(connectionString))
        {
            conn.Open();
            using (var command = conn.CreateCommand())
            {
                command.CommandType = CommandType.Text;
                command.CommandText = "INSERT INTO TestTable(Value) VALUES (@1)";
                command.Parameters.Add(new SqlParameter("1", "123456"));
                command.ExecuteNonQuery();
            }
        }
        using (var conn2 = new SqlConnection(connectionString))
        {
            conn2.Open();
            using (var command2 = conn2.CreateCommand())
            {
                command2.CommandType = CommandType.Text;
                command2.CommandText = "INSERT INTO TestTable(Value) VALUES (@1)";
                command2.Parameters.Add(new SqlParameter("1", "123456"));
                command2.ExecuteNonQuery();
            }
        }
        scope.Complete();
    }
}

ネストされた接続 - エスカレート中

static string connectionString = "data source=.\\;Integrated Security=SSPI;Database=TestDB";

static void Main(string[] args)
{
    using (var scope = new TransactionScope())
    {
        using (var conn = new SqlConnection(connectionString))
        {
            conn.Open();
            // EXECUTE INSERT
            using (var conn2 = new SqlConnection(connectionString))
            {
                conn2.Open();
                // EXECUTE INSERT 
            }
        }                
        scope.Complete();
    }
}

異なるデータベースにアクセスするネストされていない接続 - エスカレート中

トランザクション中に 2 つ以上の永続的なリソースにアクセスすると、常に DTC に昇格されます。

static string connectionString = "data source=.\\;Integrated Security=SSPI;Database=TestDB";
static string connectionString2 = "data source=.\\;Integrated Security=SSPI;Database=TestDB2";

static void Main(string[] args)
{
    using (var scope = new TransactionScope())
    {
        using (var conn = new SqlConnection(connectionString))
        {
            conn.Open();
            // EXECUTE INSERT
        }
        using (var conn2 = new SqlConnection(connectionString2))
        {
            conn2.Open();
            // EXECUTE INSERT 
        }
        scope.Complete();
    }
}

注: 実行する CRUD 操作の種類は関係ありません。常に、接続がどのように開かれ、閉じられるかによって異なります。

于 2012-12-05T13:18:33.813 に答える