我正在使用 C# 将发票的平面文件导入到数据库中。如果遇到问题,我将使用 TransactionScope 回滚整个操作。
这是一个棘手的输入文件,因为一行不一定等于一条记录。它还包括链接记录。发票将包含标题行、行项目和总计行。有些发票需要跳过,但我可能不知道需要跳过,直到达到总行数。
一种策略是将标题、行项目和总行存储在内存中,并在达到总行后保存所有内容。我现在正在追求这个。
然而,我想知道是否可以用不同的方式来完成。围绕发票创建“嵌套”事务,插入标题行和行项目,然后在达到总行数时更新发票。如果确定需要跳过发票,则此“嵌套”事务将回滚,但整个事务将继续。
这可能、实用吗?您将如何设置?
既没有TransactionScope
SQL Server 也不支持嵌套事务。
你可以筑巢TransactionScope
实例,但仅具有嵌套事务的外观。实际上,存在一种称为“环境”事务的东西,并且一次只能有一个。哪个交易是环境交易取决于你的用途TransactionScopeOption
当您创建范围时。
要更详细地解释,请考虑以下事项:
using (var outer = new TransactionScope())
{
DoOuterWork();
using (var inner1 = new TransactionScope(TransactionScopeOption.Suppress))
{
DoWork1();
inner1.Complete();
}
using (var inner2 = new TransactionScope(TransactionScopeOption.RequiresNew))
{
DoWork2();
inner2.Complete();
}
using (var inner3 = new TransactionScope(TransactionScopeOption.Required))
{
DoWork3();
inner3.Complete();
}
outer.Complete();
}
以下是每个内部作用域发生的情况:
inner1
在隐式事务中执行,独立于outer
。没有发生在DoWork1
保证是原子的。如果中途失败,您将获得不一致的数据。无论发生什么,这里发生的任何工作都将始终致力于outer
.
inner2
在新事务中执行,独立于outer
。这是一个不同的交易来自outer
但它是not嵌套的。如果失败,发生的工作outer
(DoOuterWork()
)并且任何其他范围仍然可以提交,但问题是:如果完成,则回滚整个outer
交易将not回滚内部完成的工作inner2
.这就是为什么它不是真正嵌套的。还,inner2
将无权访问由以下锁定的任何行outer
,所以如果你不小心的话,你可能会陷入僵局。
inner3
执行于same交易为outer
。这是默认行为。如果DoWork3()
失败并且inner3
永远不会完成,那么整个outer
事务被回滚。同样,如果inner3
成功完成但是outer
被回滚,然后完成的任何工作DoWork3()
也被回滚。
所以你可以希望看到这些选项实际上都不是嵌套的,并且不会给你你想要的东西。这Required
选项近似于嵌套事务,但不使您能够独立提交或回滚事务内的特定工作单元。
SQL Server 中最接近真正的嵌套事务的是SAVE TRAN
声明结合一些TRY/CATCH
块。如果您可以将逻辑放入一个或多个存储过程中,这将是一个不错的选择。
否则,您需要按照 Oded 的建议对每张发票使用单独的交易记录。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)