C# TransactionScope和手动回滚事务之间的区别?
我正在做一个别人以前开发的项目。在程序中,它执行以下操作:C# TransactionScope和手动回滚事务之间的区别?,c#,sql-server,sql-server-2008,C#,Sql Server,Sql Server 2008,我正在做一个别人以前开发的项目。在程序中,它执行以下操作: reportConnection = new SqlConnection(sConnStr); reportConnection.Open(); try { using (SqlTransaction trans = reportConnection.BeginTransaction(IsolationLevel.ReadUncommitted)) {
reportConnection = new SqlConnection(sConnStr);
reportConnection.Open();
try
{
using (SqlTransaction trans = reportConnection.BeginTransaction(IsolationLevel.ReadUncommitted))
{
......
using (SqlCommand cmd = new SqlCommand(sSQL, reportConnection, trans))
{
....
}
trans.Commit();
}
}
catch (Exception ex)
{
Logger ....
}
fianlly
{
if (reportConnection != null)
{
((IDisposable)reportConnection).Dispose();
}
}
我看到的问题是,如果using块中存在错误,它不会回滚事务。因此,这里是第一个问题:如果出现错误,将不会提交传输(也不会回滚),但会处理连接(不会处理传输)。在这种情况下,它会产生什么副作用?它是否会创建一个打开的孤立连接/事务?这样,会不会造成死锁
我做了一些搜索,似乎首选的方法是使用transactionscope(下面的代码来自microsoft):
我的第二个问题是:如果我像下面这样手动操作会怎么样。使用transactionscope有什么好处?它们真的是一样的吗
reportConnection = new SqlConnection(sConnStr);
reportConnection.Open();
try
{
using (SqlTransaction trans = reportConnection.BeginTransaction(IsolationLevel.ReadUncommitted))
{
try
{
......
using (SqlCommand cmd = new SqlCommand(sSQL, reportConnection, trans))
{
....
}
trans.Commit();
}
catch
{
try
{
// incase rollback has error
trans.Rollback();
}
catch
{
}
}
}
}
catch (Exception ex)
{
Logger ....
}
fianlly
{
if (reportConnection != null)
{
((IDisposable)reportConnection).Dispose();
}
}
谢谢。这将在
SqlTransaction
文档中介绍:
Dispose应该回滚事务。但是,
Dispose是特定于提供程序的,不应替换调用回滚
摘自:
我想这一切都取决于你有多偏执,当你认为坏的实现可能无法正常工作时,你会试图强迫它们正常工作。第一个代码示例绝对是最简单的,只有当您的提供者不能正常工作时,它才会失败
编辑复杂性示例-您的最后一个代码段应为:
try { /*...*/
using (SqlCommand cmd = new SqlCommand(sSQL, reportConnection, trans)) {
/*...*/ }
trans.Commit();
} catch { try { trans.Rollback(); } catch {} throw; }
或
?
try { /*...*/
using (SqlCommand cmd = new SqlCommand(sSQL, reportConnection, trans)) {
/*...*/ }
trans.Commit();
} catch { try { trans.Rollback(); } catch {} throw; }
try { /*...*/
using (SqlCommand cmd = new SqlCommand(sSQL, reportConnection, trans)) {
/*...*/ }
} catch { try { trans.Rollback(); } catch {} throw; }
trans.Commit();