C#中的回滚操作

9

我有两个表:enquiry和details。 在单击保存按钮时,我已经编写了以下内容:

fbsave();
fbsavedetails();

fbsave()将数据保存在enquiry表中,fbsavedetails()将数据保存在details表中。

如果在fbsavedetails()中出现错误,则两个步骤都应该回滚。

这种情况是否可能发生?


MS Access还是SQL Server? - andy
2
你是如何处理数据层的?使用存储过程吗?LINQ to SQL?连接模式还是断开模式? - Mahdi Tahsildari
你可以使用事务来实现你想要的功能,参考链接:http://msdn.microsoft.com/zh-cn/library/system.data.sqlclient.sqltransaction(v=vs.100).aspx - Raghuveer
当然可以。您能否提供这两种方法的框架以及它们的调用方式? - kush
1
“断开式架构” - 你能更具体一些吗?那太模糊、含糊和负担过重了。 - Marc Gravell
显示剩余2条评论
3个回答

8
您可以显式地创建一个事务并在其中传递,即:
using(var connection = ...)
{
    connection.Open();
    using (var tran = connection.BeginTransaction())
    {
        try
        {
            FBSave(connection, tran);
            FBSaveDetails(connection, tran);
            tran.Commit();
        }
        catch
        {
            tran.Rollback();
            throw;
        }
    }
}

注意,这里你必须 在每个命令上设置 Transaction ,因此你需要将其传递进去,并且所有命令必须在同一个连接对象上。
或者:你可以使用TransactionScope;重要的是Open()发生在TransactionScope内部以获得自动登记。
using(var tran = new TransactionScope())
{
    FBSave();
    FBSaveDetails();
    tran.Complete();
}

或者:

using(var tran = new TransactionScope())
using(var connection = ...)
{
    connection.Open();
    FBSave(connection);
    FBSaveDetails(connection);
    tran.Complete();
}

使用TransactionScope方法时,您无需设置任何特殊内容 - 大部分自动完成。当然,您可以选择将连接传递给方法,但它们也可以获取自己的连接,在大多数情况下都可以正常工作。

“在TransactionScope内打开以获得自动登记”是否可以避免使用DTC? - Mr Moose
@MrMoose 不是的,但是你通常可以通过传递连接来避免需要使用 DTC:如果你在 TransactionScope 中只使用一个连接对象,那么它将由 LTM 而不是 DTC 处理(在所有 SQL Server >= 2005 版本中,如果我没记错的话)。 - Marc Gravell

7
你可以使用TransactionScope。
using(var scope = new TransactionScope())
{
   //Complete the transaction only when both inserts succeed. 
   scope.Complete();
}

如果您没有完成Transactionscope操作,它将会被回滚。


1

解决这个问题有两种方法:

  1. 使用 DbTransaction 并在两个方法之间传递 DbTransaction,如果成功则提交事务,如果发生错误则回滚。 缺点:需要在方法之间传递 DbTransaction。
  2. 使用 TransactionScope 优点:易于使用 缺点:不支持 Access,并且如果数据库是 sql2000,则需要配置 msdtc。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接