0

SqlDataAdapter.Update を DataTables と共に使用して、1 つのトランザクションで 2 つの SQL テーブルを更新しています。いずれかの挿入が失敗した場合は、すべてのデータをロールバックします。これは私のコードです:

using (var conn = new SqlConnection(_connectionString))
{
    conn.Open();

    using (var scope = new TransactionScope())
    {
        // Insert first table
        using (var command = conn.CreateCommand())
        {
            command.CommandText =
                @"INSERT INTO TableA(Id, Data)
                  VALUES(@id, @data)";

            command.CommandType = CommandType.Text;
            command.Parameters.Add(new SqlParameter("@id", SqlDbType.Int) { SourceColumn = "Id" });
            command.Parameters.Add(new SqlParameter("@data", SqlDbType.Char) { SourceColumn = "Data" });

            var adapter = new SqlDataAdapter();
            adapter.InsertCommand = command;
            adapter.Update(tableADataTable);
        }

        // Insert second table
        using (var command = conn.CreateCommand())
        {
            command.CommandText =
                @"INSERT INTO TableB(Id, Data)
                  VALUES(@id, @data)";

            command.CommandType = CommandType.Text;
            command.Parameters.Add(new SqlParameter("@id", SqlDbType.Int) { SourceColumn = "Id" });
            command.Parameters.Add(new SqlParameter("@data", SqlDbType.Char) { SourceColumn = "Data" });

            var adapter = new SqlDataAdapter();
            adapter.InsertCommand = command;
            adapter.Update(tableBDataTable);
        }

        scope.Complete();
    }
}

私が抱えている問題は、2 番目のコマンドの実行中に例外がスローされた場合、最初のコマンドのデータがまだコミットされていることです。明示的にロールバックする必要がありますか? または、SqlDataAdapter.Update を使用するときに TransactionScope がどのように動作する必要がありますか?

注意すべき点は、もともと TransactionScope using ステートメント内で SqlConnection を作成していたことですが、DB サーバーが分散トランザクション用に正しく構成されていないというエラーを受け取ったため、それを移動しました。私の SqlConnection 作成が TransactionScope の外部にあるという事実は関連していますか?

4

3 に答える 3

2

conn.Open()呼び出しをトランザクションスコープ内に移動して、トランザクションに参加させる必要があると思います。enslist=false;また、接続文字列に含まれていないことを確認してください。

于 2010-06-22T15:36:45.543 に答える
1

SqlConnection を TransactionScope 内に配置してみてください。その後、トランザクションに自動的に参加するはずです。

あなたのコードでは、接続をトランザクションに手動で登録する必要があると思います...これらのリンクの例を確認してください。

http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.enlistdistributedtransaction(v=VS.71).aspx

http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope.aspx

申し訳ありませんが、OPをキャッチしました-おそらく、接続が既存のトランザクションに自動的に参加するように構成されていなかったためです(接続文字列のメンバーだと思います)。

Complete を呼び出さない場合 (または SqlTransaction で Commit を呼び出さない場合)、自動的にロールバックされます。

もちろん、現在のコード サンプルでは、​​複数の接続やデータベースを使用していないため、SqlTransaction オブジェクトを安全に使用できます。

于 2010-06-22T15:25:53.063 に答える