none
TransactionScopeが効かない RRS feed

  • 質問

  •  

     

    SQLServer 2005とTransactionScopeでうまくいかなくはまっています。

     

    TransactionScope内でCompleteをしなくても、SQLの処理結果がコミットされてしまいます。

    以下のソースですと、

    通常tx.Complete();を実行して、usingのスコープを抜けた時点でコミットされると期待していたのですが、

    Completeをしなくても、cmd.ExecuteNonQuery();の時点でコミットされてしまいます。

    いろいろなサイトの例を見ても、この書き方で問題はないと思うのですが、どこか注意するところが、ありますでしょうか?

    ご教授お願いいたします。

     

    using (TransactionScope tx = new TransactionScope()) {

        using (SqlConnection conn = new SqlConnection(tring.Format("Data Source={0};Initial Catalog={1};Integrated Security={2};Enlist=false;uid={3};pwd={4}", "server", "Test", "false", "id", "password")))
        using (SqlCommand cmd = conn.CreateCommand()) {
            conn.Open();
            cmd.CommandTimeout = 15;
            cmd.CommandType = CommandType.Text;

            cmd.CommandText = INSERTのSQL;
            cmd.ExecuteNonQuery();

         }

     //tx.Complete();
    }

    2007年10月8日 12:12

回答

  • こんにちは、石野です。

    普段使っているものを、あげておきます。

                using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, TimeSpan.FromMinutes(10)))
                {
                    using (SqlConnection sqlConnection = new SqlConnection(ConnectionString))
                    {
                        sqlConnection.Open();
                       
                       
    using (SqlCommand sqlCommand = new SqlCommand(InsertのSQL, conn))
               {
                   sqlCommand .ExecuteNonQuery();

                        }
                        sqlConnection.Close();
                    }

                    scope.Complete();
                }


    これで上手く行っていると思うのですが・・・

    2007年10月9日 4:27

すべての返信

  • こんにちは、石野です。

    普段使っているものを、あげておきます。

                using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, TimeSpan.FromMinutes(10)))
                {
                    using (SqlConnection sqlConnection = new SqlConnection(ConnectionString))
                    {
                        sqlConnection.Open();
                       
                       
    using (SqlCommand sqlCommand = new SqlCommand(InsertのSQL, conn))
               {
                   sqlCommand .ExecuteNonQuery();

                        }
                        sqlConnection.Close();
                    }

                    scope.Complete();
                }


    これで上手く行っていると思うのですが・・・

    2007年10月9日 4:27
  • SqlConnection に Enlist=false ( 分散トランザクションへの昇格を抑制する ) という指定は必要ですか?

    Visual Basic フォーラム: TansactionScopeを使ったTableAdapterのストアドプロシージャ実行でエラー

     

    Enlist=false を指定すると、 その接続は自動的にはトランザクションに参加しなくなるようです。
    ADO.NET と SQLCLR を使用した SQL Server 内部でのマネージ データ アクセス
    /*
    ADO.NET は、接続の Open() で Transaction.Current を自動的に確認し、意識する必要なしに、その接続をトランザクションに参加させます (ただし、enlist=false を接続文字列に指定している場合を除きます)。
    */

     

    どうしても Enlist=false にしなければならない場合。 試してみたところでは、 明示的にトランザクションに参加させてあげればよさそうでした。 ( VS2008日本語β2 + SQL Server 2005 )

    コード ブロック
        using (TransactionScope tx = new TransactionScope())
        {
            using (SqlConnection conn = new SqlConnection(CONN_STR))
            {
                using (SqlCommand cmd = conn.CreateCommand())
                {
                    conn.Open();
                    conn.EnlistTransaction(Transaction.Current); //明示的に参加させる
                    cmd.CommandTimeout = 15;
                    cmd.CommandType = CommandType.Text;

                    //...

     

     

    2007年10月9日 7:02
  • こんばんは。bs-factoryです。

     

    TransactionScope内で1つの接続のときは、うまく動作しました。

    ※複数の接続のときがうまくいきません。

     

    ありがとうございました。

     

    2007年10月10日 16:30
  •  

    こんばんは。bs-factoryです。

     

    TransactionScope内に複数のコネクションをはるには、Enlist=falseは、必要ないということですよね。

     

    今さっき、昨日までテストしていたロジックを動かしたら、期待どおりの動作をしました。

    何が、まずかったのかが不明です

     

    もしかすると、ファイアーウォールの例外にMSDTCを設定した後に、サーバーの再起動をしなかったのが原因でしょうか?

     

    とりあえずは、動作しましたので、いろいろなテストはできそうです。

    あとは、確実な設定を把握するだけです。

     

    どうもありがとうございました。

     

    2007年10月10日 16:52