我有一个父对象(DAL 的一部分),其中包含List<t>
子对象的集合()。
当我将对象保存回数据库时,我输入/更新父对象,然后遍历每个子对象。为了可维护性,我将孩子的所有代码放入单独的私有方法中。
我打算使用标准的 ADO 事务,但在旅途中,我偶然发现了 TransactionScope 对象,我相信这将使我能够在一个事务中将所有数据库交互(以及子方法中的所有交互)包装在父方法中。
到现在为止还挺好..?
所以下一个问题是如何在这个 TransactionScope 内创建和使用连接。我听说使用多个连接,即使它们连接到同一个数据库也会迫使 TransactionScope 认为它是一个分布式事务(涉及一些昂贵的 DTC 工作)。
是这样吗?或者,正如我似乎在其他地方读到的那样,使用相同的连接字符串(这将有助于连接池)的情况会很好吗?
更实际地说,我是否...
- 在父级和子级中创建单独的连接(尽管使用相同的连接字符串)
- 在父级中创建一个连接并将其作为参数传递(对我来说似乎很笨拙)
- 做点别的……?
更新:
虽然看起来我可以使用我常用的 .NET3.5+ 和 SQL Server 2008+,但该项目的另一部分将使用 Oracle (10g),因此我不妨练习一种可以跨项目一致使用的技术。
所以我将简单地将连接传递给子方法。
选项 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;
}
}
}
}