2010-06-22 88 views
0

我正在使用SqlDataAdapter.Update与DataTables更新一个事务中的两个SQL表。如果插入失败,我想回滚所有数据。这是我的代码:TransactionScope不回滚与SqlDataAdapter.Update

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(); 
    } 
} 

我遇到的问题是,如果一个例外是第二个命令执行过程中引发的,从第一个命令数据仍COMMITED。我是否需要明确回滚?或者当使用SqlDataAdapter.Update时,TransactionScope应该如何表现?

需要注意的是,最初我在TransactionScope using语句中创建了SqlConnection,但是当我收到错误时,我的数据库服务器没有正确配置分布式事务。是否我的SqlConnection创建与TransactionScope相关?

回答

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上提交),它会自动回滚。

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

2

我认为您需要将您的conn.Open()调用移入事务范围内,以便它自己进入事务。另外,请确保您的连接字符串中没有enslist=false;

0

尝试插入码

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

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