一次调用ExecuteNonQuery()原子

时间:2018-08-16 12:00:34

标签: c# .net sql-server transactions transactionscope

是对ExecuteNonQuery()原子的一次调用,还是在单个DbCommand中包含多个sql语句的情况下使用事务有意义?

请参阅我的示例进行澄清:

using (var ts = new TransactionScope())
{
    using (DbCommand lCmd = pConnection.CreateCommand())
    {
        lCmd.CommandText = @"
            DELETE FROM ...;
            INSERT INTO ...";
      lCmd.ExecuteNonQuery();
    }
    ts.Complete();
}

3 个答案:

答案 0 :(得分:4)

如果您不要求交易,您(大多数)就不会获得交易。 SQL Server需要事务中的所有内容,因此,默认情况下(无其他事务管理),对于每个单独的语句,SQL Server将创建一个事务并自动提交它。因此,在您的示例中(如果没有TransactionScope),您将获得两个单独的事务,分别独立提交或回滚(出错)。

(除非您已在该连接上打开IMPLICIT_TRANSACTIONS,在这种情况下,您将获得一笔交易,但最后需要显式COMMITROLLBACK。唯一我发现使用此模式的人员是从Oracle移植并试图最小化更改的人员。我不建议将其打开以进行未完成的工作,因为这只会使习惯于SQL Server默认设置的人员感到困惑

答案 1 :(得分:2)

不是。 SQL引擎会将此文本视为两个单独的指令。 TransactionScope是必需的(或任何其他形式的事务,即,如果愿意,可以使用SQL文本中的隐式BEGIN TRAN-COMMIT)。

答案 2 :(得分:1)

否,因为上述答案表明该命令(与该命令中的单个语句相反)将不会在事务内运行

将很容易验证

示例代码

create table t1
(
    Id int not null,
    Name text
)


using (var conn = new SqlConnection(...))
using (var cmd = conn.CreateCommand())
{
    cmd.CommandText = @"
         insert into t1 values (1, 'abc');
         insert into t1 values (null, 'pqr');
    ";
    cmd.ExecuteNonQuery();
}

第二条语句将失败。但是第一条语句将执行,并且表中将有一行。