我試圖做一個快速的虛擬應用程序,所以我可以瞭解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