我试图做一个快速的虚拟应用程序,所以我可以了解System.Transactions的来龙去脉。这个应用程序与2个不同的SQLExpress数据库进行交互。如果我在组件服务中提取事务统计信息,则可以在打开第二个连接时在outerScope中看到事务启动。如果failOuter为true,则事务中止,但不会抛出任何异常。当failInner为true时,会引发TransactionAbortedException。试图了解TransactionScope
从MSDN:
当你的应用程序完成所有它想要在交易完成工作,你应该调用Complete方法只有一次告知事务管理器,它是可以接受的提交事务。将调用完成为使用块中的最后一条语句是非常好的做法。
无法调用此方法会中止事务,因为事务管理器将此解释为系统故障,或等同于事务范围内引发的异常。
如果作用域创建事务并且事务被中止,则会引发TransactionAbortedException。
基于这一点,我期望我的outerScope抛出一个TransactionAbortedException,因为我的事务统计显示一个中止事务每次我运行我的应用程序与failOuter设置为true。我的方法返回true,因为即使事务中止也不会抛出异常。除非我放弃内部交易,否则它的行为如我所料。任何澄清将不胜感激。
public bool CreateNestedTransaction(bool failOuter, bool failInner)
{
try
{
using (TransactionScope outerScope = new TransactionScope())
{
/* Perform transactional work here */
using (SqlConnection myConnection = new SqlConnection("server=(local)\\SQLExpress;Integrated Security=SSPI;database=test1"))
{
SqlCommand myCommand = new SqlCommand();
myConnection.Open();
myCommand.Connection = myConnection;
myCommand.CommandText = "update test set Value = ((select Value from test where Id = (select max(Id) from test))+1) where Id = (select max(Id) from test)";
myCommand.ExecuteNonQuery();
}
using (SqlConnection myConnection = new SqlConnection("server=(local)\\SQLExpress;Integrated Security=SSPI;database=test1"))
{
SqlCommand myCommand = new SqlCommand();
myConnection.Open();
myCommand.Connection = myConnection;
myCommand.CommandText = "update test set Value = Value";
myCommand.ExecuteNonQuery();
}
using (TransactionScope innerScope = new TransactionScope())
{
using (SqlConnection myConnection = new SqlConnection("server=(local)\\SQLExpress;Integrated Security=SSPI;database=test2"))
{
SqlCommand myCommand = new SqlCommand();
myConnection.Open();
myCommand.Connection = myConnection;
myCommand.CommandText = "update test set Value = ((select Value from test where Id = (select max(Id) from test))+1) where Id = (select max(Id) from test)";
myCommand.ExecuteNonQuery();
}
if (failInner == false) { innerScope.Complete(); }
}
if (failOuter == false) { outerScope.Complete(); }
}
}
catch (TransactionAbortedException)
{
return false;
}
return true;
}
是的,这是有道理的。我认为MSDN的最后一行是把我抛弃。我正在看我的交易中止,并期待一个例外。感谢您的解释!有没有办法判断我的外部异常是否中止?我想在这种情况下返回false。 – 2009-04-24 18:57:47