LINQ2SQL是否自动将ExecuteCommand放入事务中

时间:2016-04-20 10:48:10

标签: c# sql-server linq linq-to-sql transactions

此答案的文档引用是:https://stackoverflow.com/a/542691/1011724

  

当您调用SubmitChanges时,LINQ to SQL会检查调用是否在Transaction的范围内,或者Transaction属性(IDbTransaction)是否设置为用户启动的本地事务。 如果找不到任何事务,LINQ to SQL将启动本地事务(IDbTransaction)并使用它来执行生成的SQL命令。当所有SQL命令都成功完成后,LINQ to SQL将提交本地事务和回报。

适用于.ExecuteCommand()方法?换句话说,我是否可以相信以下删除是在事务中处理的,如果失败则会自动回滚,或者我是否需要手动告诉它使用事务,如果是,如何?我应该使用TransactionScope吗?

using(var context = Domain.Instance.GetContext())
{
    context.ExecuteCommand("DELETE FROM MyTable WHERE MyDateField = {0}", myDate)
}

1 个答案:

答案 0 :(得分:2)

每个SQL语句,无论是否包装在显式事务中,都是以事务方式发生的。因此,显式事务与否,单个语句总是 atomic - 它们要么完全发生,要么根本不发生。在上面的示例中,要么删除符合条件的所有行,要么删除所有行 - 这与客户端代码的作用无关。实际上没有办法让SQL Server部分删除行;甚至扯掉电源线只会意味着当服务器重新启动并读取事务日志时,已经完成的任何操作都将被撤消。

美中不足的是,匹配的行可能会因语句的锁定方式而异。该语句逻辑上分两个阶段发生,第一阶段确定将删除哪些行,第二阶段实际删除它们(在更新锁定时)。例如,如果您发布了此语句,并且在运行时发出了INSERT,其中插入了符合DELETE条件的行,则DELETE之后该行是否在数据库中已完成取决于哪些事务隔离级别对语句有效。因此,如果您希望实用保证"所有行"被删除,什么客户端代码进入范围。但这有点超出原始问题的范围。