mar*_*c_s 28 sql-server ado.net transactions transactionscope
我已经"继承"了一个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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我最近一直在阅读很多关于.NET TransactionScope类的内容,我想知道,这里首选的方法是什么?通过切换使用,我可以获得任何东西(可读性,速度,可靠性)
using (TransactionScope _scope = new TransactionScope())
{
using (SqlConnection _con = new SqlConnection(_connectionString))
{
....
}
_scope.Complete();
}
Run Code Online (Sandbox Code Playgroud)
你更喜欢什么,为什么?
渣
Joh*_*ers 16
您不会通过切换现有代码立即获得任何收益TransactionScope
.由于它提供的灵活性,您应该将它用于未来的开发.它将使将ADO.NET调用以外的东西包含在事务中变得更加容易.
顺便说一句,在您发布的示例中,SqlCommand
实例应该是using
块.
我更喜欢TransactionScope.它并不适用于所有场景,但在您描述的场景中,它是更好的解决方案.
我的推理:
总之,结果是代码少一些,而且设计通常更加健壮,因为系统正在为我处理一些细节; 这是我必须记住的事情.
此外,当您在DAL中有许多嵌套方法时,透明的事务注册会特别有用 - 尽管您必须注意不要让您的事务变成需要DTC的分布式方法,如果您使用多个SqlConnections,即使它们指向同一个DB.
Microsoft建议使用事务范围:
http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope.aspx
基本思想是事务范围将为您管理"环境事务上下文".首先,您与一个数据库交谈,您有一个SQL事务,然后您与数据库2进行通信,并将事务提升为分布式事务.
事务范围对您有用,因此您可以专注于系统的功能,而不是管道.
编辑
使用事务范围时,事务中涵盖该范围内的所有内容.因此,保存一行代码,将命令连接到事务.这可能是错误的来源,例如,如果在1000中有一个机会忘记了这一行,那么你会丢失多少.
编辑2
同意以下对Triynko的评论.但是,我们使用Entity Framework,EF会自动关闭并重新打开连接,以便在事务中登记它.它不会在物理上关闭连接,它会将其释放到连接池并获取一个新连接,它可以是相同的,也可以是不同的连接.