我有一個父對象(DAL的一部分),其中包含子對象的集合(List<t>
)。TransactionScope:避免分佈式事務
當我將對象保存回數據庫時,我輸入/更新父對象,然後遍歷每個子對象。爲了可維護性,我將孩子的所有代碼放入一個單獨的私有方法中。我想要使用標準的ADO Transactions,但是在我的旅行中,我偶然發現了TransactionScope對象,我相信這將使我能夠在父方法中包含所有數據庫交互(以及子方法中的所有交互)在一次交易中。
到目前爲止這麼好..?
所以下一個問題是如何創建和使用此TransactionScope內的連接。我聽說使用多個連接,即使它們是同一個數據庫,也會強制TransactionScope認爲它是一個分佈式事務(涉及一些昂貴的DTC工作)。
是這樣嗎?或者是,因爲我似乎正在讀其他地方,使用相同的連接字符串(這將適用於連接池)將罰款?
更實際地說,我...
- 創建父&孩子單獨的連接(儘管有相同的連接字符串)
- 創建父連接的通過將它作爲參數(對我來說似乎笨拙)
- 做別的事...?
UPDATE:
雖然看起來我會用我平時.NET3.5 +和SQL Server 2008+即可,該項目的另一部分將使用Oracle(10克),所以我不妨嘗試一種可以在整個項目中一致使用的技術。
所以我只是簡單地將連接傳遞給子方法。
選項1個代碼示例:
using (TransactionScope ts = new TransactionScope())
{
using (SqlConnection conn = new SqlConnection(connString))
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.Connection = conn;
cmd.Connection.Open();
cmd.CommandType = CommandType.StoredProcedure;
try
{
//create & add parameters to command
//save parent object to DB
cmd.ExecuteNonQuery();
if ((int)cmd.Parameters["@Result"].Value != 0)
{
//not ok
//rollback transaction
ts.Dispose();
return false;
}
else //enquiry saved OK
{
if (update)
{
enquiryID = (int)cmd.Parameters["@EnquiryID"].Value;
}
//Save Vehicles (child objects)
if (SaveVehiclesToEPE())
{
ts.Complete();
return true;
}
else
{
ts.Dispose();
return false;
}
}
}
catch (Exception ex)
{
//log error
ts.Dispose();
throw;
}
}
}
}
請參閱[在某些機器上TransactionScope自動升級到MSDTC?](http://stackoverflow.com/questions/1690892/transactionscope-automatically-escalating-to-msdtc-on-some-machines/1693795#1693795)。有幾個很好的答案,但我鏈接的是最簡潔的(並與您的問題相關)。結果是,如果您使用.NET 2.0和SQL Server 2005,即使使用具有相同連接字符串的兩個連接,您也會升級。這對於.NET 3.5和SQL Server 2008來說並不是問題。 – 2010-07-06 15:36:21
我一般都使用.NET 3.5/4和SQL 2008,但偶爾我可能會使用SQL2005/2000,所以無論如何它值得記住。謝謝 – CJM 2010-07-06 15:44:08
任何人都可以給我一些關於什麼是分佈式事務的知識。用例子來解釋。 – Thomas 2016-02-04 14:33:05