3

我需要帮助来实现相当复杂的业务逻辑,它在许多表上运行并执行相当多的 SQL 命令。但是我想确保数据不会处于不一致的状态,到目前为止,我还没有看到不需要嵌套事务的解决方案。我写了一个简单的伪代码,它说明了一个类似于我想要完成的场景:

Dictionary<int, bool> opSucceeded = new Dictionary<int, bool> ();

for (int i = 0; i < 10; i++)
{
    try
    {   
        // this operation must be atomic
        Operation(dbContext, i);

        // commit (?)

        opSucceeded[i] = true;
    }
    catch
    {
        // ignore
    }
}

try
{
    // this operation must know which Operation(i) has succeeded;
    // it also must be atomic
    FinalOperation(dbContext, opSucceeded);

    // commit all
}
catch
{
    // rollback FinalOperation and operation(i) where opSucceeded[i] == true
}

对我来说最大的问题是:如何确保如果 FinalOperation 失败,所有成功的操作 Operation(i) 都回滚?请注意,我也希望能够忽略单个操作(i)的失败。

是否可以通过使用嵌套的 TransactionScope 对象来实现这一点,如果没有 - 你将如何解决这样的问题?

4

1 回答 1

2

如果我在关注您的问题,您希望对数据库进行一系列操作,并捕获足够的信息来确定每个操作是成功还是失败(简化代码中的字典)。

从那里,您有一个最终操作,如果它本身失败,则必须回滚之前的所有成功操作。

看起来这正是简单交易所针对的案例类型。只要最终操作的失败将整个事务回滚(此处假设 FinalOperation 出于其他原因未使用该信息),就无需跟踪子/早期操作的成功或失败。

只需在进入所描述的块之前启动事务,并在知道 FinalOperation 的状态后提交或回滚整个事务。从您当前的描述中可以看出,没有必要嵌套子操作。

也许我错过了什么?(注意,如果您想保留较早的/子操作,那将是完全不同的事情......但是最终操作的失败将整个操作包回滚会使简单的事务可用)。

于 2008-10-21T23:00:59.970 回答