gpt4 book ai didi

.net - C# 事务中的事务

转载 作者:行者123 更新时间:2023-12-02 11:43:34 25 4
gpt4 key购买 nike

我正在使用 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在隐式事务中执行,独立于 outerDoWork1 中没有发生任何事情保证是原子的。如果中途失败,您将获得不一致的数据。此处发生的任何工作始终都会提交,无论 outer 发生什么情况。 .

  • inner2在新事务中执行,独立于 outer 。这是与 outer 不同的交易但它嵌套。如果失败,outer中发生的工作( DoOuterWork() ) 和任何其他范围仍然可以提交,但问题是:如果完成,则回滚整个 outer事务将不会回滚 inner2 内完成的工作. 这就是它不是真正嵌套的原因。另外,inner2将无权访问由 outer 锁定的任何行,所以如果你不小心,你可能会在这里陷入僵局。

  • inner3在与outer相同的交易中执行。这是默认行为。如果DoWork3()失败并且 inner3永远不会完成,那么整个outer事务被回滚。类似地,如果 inner3成功完成但 outer回滚,然后 DoWork3() 中完成的任何工作也被回滚。

所以你可以看到这些选项实际上都不是嵌套的,并且不会给你你想要的东西。 Required选项近似于嵌套事务,但无法让您独立提交或回滚事务内的特定工作单元。

在 SQL Server 中您可以获得的最接近真正嵌套事务的是 SAVE TRAN结合一些声明TRY/CATCH block 。如果您可以将逻辑放入一个或多个存储过程中,这将是一个不错的选择。

否则,您需要按照 Oded 的建议对每张发票使用单独的交易。

关于.net - C# 事务中的事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2794761/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com