0

我试图解决的问题如下:

我有一个从文件中提取数据并在多个表中插入某些内容的过程,因为它现在是通过一个事务完成的,但是对于非常大的数据集,回滚或提交超时并失败,不管我是什么将时间设置为(至少就我所有的尝试都表明)。所以决定我需要重写功能来“切碎”任务。就目前而言,当前代码的伪代码看起来像(用于避免不必要信息的伪代码)

variable = FunctionThatReadsFromAFile();

ITransactionManager transactionObject = new TransactionManager();
IDbTransaction dbTransaction = transactionObject.Get();

WriteToFirstTable(variable ,dbTransaction);
WriteToSecondtable(variable ,dbTransaction);
WriteToThirdTable(variable ,dbTransaction);

if(!Error)
transactionObject.Commit(dbTransaction);
else
transactionObject.Rollback(dbTransaction);

就像我说的,这适用于较小的数据集,但是当文件具有超过特定数量的行(取决于超时)时,它会在提交或回滚时失败。

例如,我不能只将超时更改为 10,000 秒,事实上,由于程序的结构方式,我根本无法更改超时以用于测试目的。所以我想要做的是让程序一次处理 100 行而不是一次处理整个文件,提交它们,但是如果“百组”中的一个失败,我会回滚所有内容,我明白了这可以通过嵌套事务来完成,但是这样做;

using (TransactionScope outterTransaction = new TransactionScope())
{

    while(file.read()) 
    {

        using (TransactionScope innerTransaction = new TransactionScope())

        {

        variable = GetNextHundredOrLessRows(file); //100 rows at a time basically

        WriteToFirstTable(variable ,innerTransaction );

        WriteToSecondtable(variable ,innerTransaction );

        WriteToThirdTable(variable ,innerTransaction);


        if(!Error)
        innerTransaction.Complete();
        else
        innerTransaction.Rollback();

        }

    }

    if(!Error)
        outterTransaction.Complete();
        else
        outterTransaction.Rollback();

}

不工作,知道我做错了什么吗?

提前感谢大家抽出时间来帮助我。

编辑:这也是解决问题的正确途径吗?我已经读过嵌套事务加入了外部事务的范围,所以我仍然会在 .Complete 上遇到同样的问题吗?

4

1 回答 1

0

我相信你需要在循环的底部提交事务(这会导致你需要考虑的其他问题,即如何回滚)。如果你等到你在内部事务循环之外,所有事务将被捆绑并立即提交,这意味着性能实际上会比第一个示例的性能差得多。

编辑:如前所述,这会导致一个问题,如果一组插入失败,您将无法回滚更改。为了解决这个问题,我认为最简单的解决方案是创建一个“RollBackStack”。在 while 循环中,您将一些对象与执行回滚所需的任何数据推送到堆栈上。您添加一个标志来指示是否有故障。如果出现故障,则切换标志并从循环中中断。然后弹出堆栈撤消更改,直到堆栈为空。然后您就知道数据库处于您开始之前的状态。之后,您可以从组 1 重试插入。或者,您可以添加重试逻辑以从组 x 继续,其中 x 是您在执行任何回滚之前失败的组。

于 2013-05-02T16:30:21.847 回答