我已经“继承”了一个C#方法,它创建了一个ADO.NET SqlCommand对象,并循环遍历要保存到数据库的项目列表(SQL Server 2005)。
现在,使用传统的SqlConnection / SqlCommand方法,为了确保一切正常,将两个步骤(删除旧条目,然后插入新条目)包装到ADO.NET SqlTransaction中。
using (SqlConnection _con = new SqlConnection(_connectionString))
{
using (SqlTransaction _tran = _con.BeginTransaction())
{
try
{
SqlCommand _deleteOld = new SqlCommand(......., _con);
_deleteOld.Transaction = _tran;
_deleteOld.Parameters.AddWithValue("@ID", 5);
_con.Open();
_deleteOld.ExecuteNonQuery();
SqlCommand _insertCmd = new SqlCommand(......, _con);
_insertCmd.Transaction = _tran;
// add parameters to _insertCmd
foreach (Item item in listOfItem)
{
_insertCmd.ExecuteNonQuery();
}
_tran.Commit();
_con.Close();
}
catch (Exception ex)
{
// log exception
_tran.Rollback();
throw;
}
}
}
现在,我最近一直在阅读有关.NET TransactionScope课程的很多内容,我想知道,这里的首选方法是什么?通过切换到使用
,我可以获得任何东西(可读性,速度,可靠性)using (TransactionScope _scope = new TransactionScope())
{
using (SqlConnection _con = new SqlConnection(_connectionString))
{
....
}
_scope.Complete();
}
您更喜欢什么,为什么?
马克
答案 0 :(得分:16)
通过切换现有代码以使用TransactionScope
,您无法立即获得任何收益。由于它提供的灵活性,您应该将它用于未来的开发。它将使以后更容易将除ADO.NET调用之外的内容包含在事务中。
顺便说一下,在您发布的示例中,SqlCommand
个实例应该在using
块中。
答案 1 :(得分:8)
Microsoft建议使用事务范围:
http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope.aspx
基本思路是交易范围将为您管理“环境交易上下文”。您首先与一个数据库交谈,您有一个sql事务,然后您与数据库2进行通信,并将事务提升为分布式事务。
交易范围对您有用,因此您可以专注于系统的功能,而不是管道。
修改强>
当您使用事务范围时,该范围内的所有内容都由事务涵盖。因此,保存一行代码,将命令连接到事务。这可能是错误的来源,例如,如果在1000中有一个机会忘记了这一行,那么你会丢失多少。
编辑2
同意以下对Triynko的评论。但是,我们使用Entity Framework,EF会自动关闭并重新打开连接,以便在事务中登记它。它不会在物理上关闭连接,它会将它释放到连接池并获得一个新连接,它可以是相同的,也可以是不同的连接。
答案 2 :(得分:8)
我更喜欢TransactionScope。它并不适用于所有场景,但在您描述的场景中,它是更好的解决方案。
我的推理:
由于系统正在为我处理一些细节,因此结果是代码少了一些,而且设计通常更加健壮。这是我必须记住的事情。
此外,如果您的DAL中有许多嵌套方法,透明的交易注册会特别有用 - 尽管您必须注意不要让您的交易变成需要DTC的分布式方法,如果您使用多个SqlConnections,即使它们指向同一个数据库,也会发生这种情况。
答案 3 :(得分:6)
请注意使用事务范围有时我们会遇到很多问题,因为我们必须在服务器中设置许多设置,例如设置DTC,防火墙等等。所以我建议使用SqlTransaction在实现中更省钱。
答案 4 :(得分:2)
好吧,也许为时已晚......但无论如何,我会为那些感兴趣的人写下来......
由于我现在有一个更好的图片,在我目前基于SqlTransaction
的方法遇到很多困难之后,我可能会更改为TransactionScope
,正如我所看到的那样... ... TransactionScope
是可以在业务层中轻松使用。
答案 5 :(得分:2)
也迟到了......你可以很容易地拥有"嵌套"即使数据库不支持嵌套事务,业务层中的事务也是如此。 .NET控制嵌套并最终使用一个数据库事务(至少在SQL Server 2008+的情况下)。这使得在原始意图之外重用数据访问代码变得更加容易,作为更大事务的一部分。