LINQ to SQL 中的嵌套事务

Nested transactions in LINQ to SQL

提问人:user29930 提问时间:10/21/2008 更新时间:10/22/2008 访问量:1918

问:

我需要帮助来实现相当复杂的业务逻辑,该逻辑在许多表上运行并执行相当多的 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) 都会回滚?请注意,我还希望能够忽略单个 Operation(i) 的失败。

是否可以通过使用嵌套的 TransactionScope 对象来实现这一点,如果不能 - 您将如何处理此类问题?

嵌套的 SQL LINQ 事务

评论


答:

2赞 Godeke 10/22/2008 #1

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

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

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

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

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