【问题标题】:C# Should I place the Sql/OleDb transaction.Commit() outside of a for loop?C# 我应该将 Sql/OleDb transaction.Commit() 放在 for 循环之外吗?
【发布时间】:2017-06-16 06:51:38
【问题描述】:

我有以下基本的 oledb 循环:

using (OleDbConnection conn = new OleDbConnection(Con))
{
    using (OleDbCommand cmd = new OleDbCommand())
    {
        for loop 
        {
        cmd.Connection = conn;
        conn.Open();
        transaction = conn.BeginTransaction(IsolationLevel.ReadCommitted);
        cmd.CommandText = "row by row insert"
        cmd.Some parameters, then ExecuteNonQuery
        transaction.Commit();
        }
    }
}

但是,我不确定是否应该在命令执行后将Commit 放在循环中。毕竟我应该放置它吗?概述using 将是一个try catch,在catch 中包含一个回滚。所以我猜如果我想能够回滚我的所有更改,我会希望循环完全运行,然后提交?

我也刚刚了解了TransactionScopes,它在使用中概述了 SQL 上下文,所以我也想知道它是如何应用的。

【问题讨论】:

  • 取决于您的要求。如果一个失败,是否应该重置所有INSERT 命令?
  • 是的,我想是的。因此,如果它在循环内,则最多回滚的捕获将是添加的最后一行?另外,我正在尝试使用 TransactionScope,我添加了参考等,我认为这将适用于任何与平台无关的数据库?因为我看不到任何地方可以定义它。 @JanesAbouChleih
  • 没错,您现在的代码只会重置最后一个INSERT 的事务。如果你把它放在循环之外(当然是conn.BeginTransaction(IsolationLevel.ReadCommitted);),它将重置在这个事务/for循环中处理的所有INSERT命令。但是现在,在处理transaction.Rollback() 的地方仍然缺少一些异常处理。 €:正如@Mike Nakis 已经说过的那样,它也会对您的数据库的性能产生巨大影响,因为所有事务都被记录下来。因此更少的事务=更快的性能。我不明白TransactionScope 的问题。

标签: c# transactions transactionscope


【解决方案1】:

BeginTransaction() 调用在循环内时,您不能将Commit() 调用移到循环外。要么两者都留在循环中,要么都离开循环。

所以,您的问题应该是:“我应该在循环的每次迭代中执行一个事务,还是应该开始一个事务,执行我的循环,然后提交事务?”

好吧,每次迭代执行一个事务的唯一原因是极不可能的情况,即您希望提交所有非失败插入,即使其中一些失败。 (在这种情况下,您还需要进行一些异常处理。)

如果您没有这样的要求,并且如果您不介意数量级的性能改进,那么您最好启动一个事务,执行您的循环,然后关闭您的事务。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-28
    • 1970-01-01
    • 2020-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-17
    • 1970-01-01
    相关资源
    最近更新 更多