我想解决的问题如下:
我有一个进程从文件中提取数据并在多个表中插入某些内容,因为现在它完全由一个事务完成,但是对于非常大的数据集,回滚或提交超时并失败,没有无论我把时间设定为什么(至少就我的所有尝试都表明的那样)。所以决定我需要重写功能来“完成”任务。因为它当前代表当前代码的伪代码看起来像(用于避免不必要信息的伪代码)
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上遇到同样的问题吗?
答案 0 :(得分:0)
我认为你需要在循环的底部提交事务(这将导致你需要考虑的其他问题,即如何回滚)。如果您等到内部事务循环之外,所有事务将立即捆绑并提交,这意味着性能实际上将远远低于第一个示例的性能。
编辑:如上所述,这会导致一个问题,即如果一组插入失败,则无法回滚更改。为了解决这个问题,我认为最简单的解决方案是创建一个“RollBackStack”。在while循环中,你可以用一些回滚到堆栈所需的数据来推送一些对象。您添加一个标志以指示某些内容是否失败。如果发生故障,则切换标志并从循环中断。然后弹出堆栈撤消更改,直到堆栈为空。然后,您知道db处于启动之前的状态。之后,您可以从组1重试插入。或者,您可以添加重试逻辑以从组x继续,其中x是在执行任何回滚之前失败的组。如果经过一定次数的重试后,您无法完成完整插入,则进入回滚方法,在该方法中将堆栈弹出为空。