代码之家  ›  专栏  ›  技术社区  ›  Rob Bell

TransactionScope未使用SqlDataAdapter.Update回滚

  •  0
  • Rob Bell  · 技术社区  · 15 年前

    我正在使用SqlDataAdapter.Update with DataTables在一个事务中更新两个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();
        }
    }
    

    需要注意的是,最初我在TransactionScope using语句中创建了SqlConnection,但由于收到错误,我的DB服务器没有为分布式事务正确配置,所以我将其移出。我的SqlConnection创建在TransactionScope之外这一事实是否与此相关?

    3 回复  |  直到 15 年前
        1
  •  1
  •   Adam Houldsworth    15 年前

    尝试将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

    抱歉,刚才抓到了您的操作-可能是因为连接没有配置为自动登记到现有事务中(我认为是连接字符串的一个成员)。

    当然,在当前的代码示例中,您可以安全地使用SqlTransaction对象,因为您不涉及多个连接/数据库。

        2
  •  2
  •   Mark Wilkins    15 年前

    conn.Open() 在事务作用域内调用,以便它将自己登记到事务中。另外,确保您没有 enslist=false; 在连接字符串中。

        3
  •  0
  •   Ramgy Borja    8 年前

    command.CommandText = @"SET autocommit = 0";
    command.ExecuteNonQuery();
    
    command.CommandText = @"SET sql_mode=TRADITIONAL";
    command.ExecuteNonQuery();