C# 如何处理if DbTransaction';s Commit()或Rollback()引发异常?

C# 如何处理if DbTransaction';s Commit()或Rollback()引发异常?,c#,sql-server,transactions,C#,Sql Server,Transactions,我正在使用Visual Studio 2012和MS SQL Server 2008 R2 在我的代码中,我使用的是DbConnection和DbTransaction。这是我的代码: DbConnection dbConnection = null; DbTransaction dbTransaction = null; try { dbConnection = DbProviderFactories.GetFactory("System.Data.SqlClient").Create

我正在使用Visual Studio 2012和MS SQL Server 2008 R2

在我的代码中,我使用的是
DbConnection
DbTransaction
。这是我的代码:

DbConnection dbConnection = null;
DbTransaction dbTransaction = null;

try
{
   dbConnection = DbProviderFactories.GetFactory("System.Data.SqlClient").CreateConnection();
   dbConnection.ConnectionString = connectionString;
   dbConnection.Open();
   dbTransaction = dbConnection.BeginTransaction();
   // do my work using dbConnection and dbTransaction
   dbTransaction.Commit();
} 
catch (MyWorkFailedException mwfe)
{
   dbTransaction.Rollback();
   throw;
}
finally
{
   if (dbConnection != null)
   {
      dbConnection.Close();
      dbConnection.Dispose();
   }
}
是否有可能
dbTransaction.Commit()
dbTransaction.Rollback()引发异常


如果是,那么如何在我的代码中处理它?c#程序员通常如何处理这种情况?或者他们不处理这种情况?

您将任何方法中的异常(包括
Commit
Rollback
)处理为事务中的失败。如果你想/不得不这样做,你可以清理C代码中的一些东西。数据库清理将自动处理(至少对于符合ACID的数据库而言)。

是的,
Commit
Rollback
都可以引发异常。但是,这些可能应该向上传播,并记录或向用户显示为错误。如何处理错误完全取决于您自己,但通常错误是由关闭的连接造成的。其次,您应该利用
使用

using (var dbConnection  = DbProviderFactories.GetFactory("System.Data.SqlClient").CreateConnection())
{
    dbConnection.ConnectionString = connectionString;
    dbConnection.Open();
    using (var dbTransaction = dbConnection.BeginTransaction())
    {
        //Do work here

        dbTransaction.Commit();
    }
}
DbTransaction
将自动回滚其dispose方法(假设尚未提交)。此代码引发的异常通常是无法正常处理的。在大多数情况下,它们可能来自SQL错误(无效语法、FK错误等)或关闭的连接


只要您有一个好的日志系统,上面的代码就应该是您所需要的。

使用
TransactionScope
,它只有
Complete()
。一旦它被释放,它将回滚底层事务。任何异常都会导致基础事务回滚:

using (var scope = new TransactionScope())
using (var connection = new SqlConnection(...))
{
    // do stuff

    scope.Complete();
}

为什么在你的代码中没有一个
使用
?@SergRogovtsev不是我使用
的方式最后尝试
与使用
使用
进行
数据库连接
相同?如果是,那么这只是一个偏好和旧习惯。基本上是一样的,但您很容易出错(例如,在代码中,您可以尝试回滚不存在的事务)<代码>使用
是您应该利用的好模式。@sergRogovtsev“使用是您应该利用的好模式”->在出现WCF客户端(已知错误)的情况下,您不一定要将其包装在try catch finnaly中以处理disposeexplicitly@bet,这不是WCF客户端。为什么需要它而不是清除
new SqlConnection()
?我确实需要向上传播异常并向用户显示为错误。我在上面的代码中做了更改,在回滚后再次抛出
myworkfailedeexception
。假设我有一个自定义异常
InfrastructureException
;如果提交或回滚失败,您将如何在代码中抛出此异常?我认为只有当您的事务跨越多个数据库时才需要
TransactionScope
?实际上,它不适用于任何兼容的提供程序,并且比使用Rob回答中的
DbTransaction
更干净。