C# 如何处理if DbTransaction';s Commit()或Rollback()引发异常?
我正在使用Visual Studio 2012和MS SQL Server 2008 R2 在我的代码中,我使用的是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
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
更干净。