开发者社区> 问答> 正文

如何回滚已经用SqlTransaction执行的所有SqlCommands?我有以下代码

public void Execute(string Query, params SqlParameter[] Parameters)
{
    using (var Connection = new SqlConnection(Configuration.ConnectionString))
    {
        Connection.Open();

        using (var Command = new SqlCommand(Query, Connection))
        {
            if (Parameters.Length > 0)
            {
                Command.Parameters.Clear();
                Command.Parameters.AddRange(Parameters);
            }

            Command.ExecuteNonQuery();
        }
    }
}

对于不同的查询,该方法可能被调用2次或3次,但方式相同。

例如:

插入员工 插入员工证书 在另一个表上更新Employee的程度[失败可能会在这里导致。例如 ] 如果Point [3]失败,则不应执行所有已提交的命令,而必须回滚。

我知道我可以放在SqlTransaction上面并使用Commit()方法。但是如果失败了,第三点呢?我认为只有第3点会回滚,而其他1,2点不会?如何解决这个问题,我应该怎么做?

我应该使用SqlCommand[]数组吗?我该怎么办?

我只在CodeProject中找到类似的问题:

展开
收起
祖安文状元 2020-01-03 15:49:45 622 0
1 条回答
写回答
取消 提交回答
  • 在不更改Execute方法的情况下,您可以执行此操作

    var transactionOptions = new TransactionOptions();
        transactionOptions.IsolationLevel = IsolationLevel.ReadCommitted;
        transactionOptions.Timeout = TransactionManager.MaximumTimeout;
    
        using (var tran = new TransactionScope(TransactionScopeOption.Required, transactionOptions)
        {
           Execute("INSERT ...");
           Execute("INSERT ...");
           Execute("UPDATE ...");
    
           tran.Complete();
        }
    

    在不更改Execute方法的情况下,您可以执行此操作

    var transactionOptions = new TransactionOptions();
    transactionOptions.IsolationLevel = IsolationLevel.ReadCommitted;
    transactionOptions.Timeout = TransactionManager.MaximumTimeout;
    
    using (var tran = new TransactionScope(TransactionScopeOption.Required, transactionOptions)
    {
       Execute("INSERT ...");
       Execute("INSERT ...");
       Execute("UPDATE ...");
    
       tran.Complete();
    }
    

    SqlClient将缓存在事务中登记的内部SqlConnection,并将其重新用于每次Execute调用。因此,您甚至最终会遇到本地(非分布式)事务

    2020-01-03 15:50:10
    赞同 展开评论 打赏
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载