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)がロールバックされるようにする方法です。また、単一のOperation(i)の失敗を無視できるようにしたいと思います。

ネストされたTransactionScopeオブジェクトを使用してこれを実現することは可能ですか?そうでない場合は、そのような問題にどのようにアプローチしますか?

4

1 に答える 1

2

私があなたの質問に従っている場合、データベースに対して一連の操作を行う必要があり、各操作が成功するか失敗するかを判断するのに十分な情報を取得します (簡略化されたコードの辞書)。

そこから、それ自体が失敗した場合に、以前に成功したすべての操作をロールバックする必要がある最終操作があります。

これはまさに、単純なトランザクションが対象とするタイプのケースのように思われます。最終操作の失敗によってトランザクション全体がロールバックされる限り、子/初期操作の成功または失敗を追跡する必要はありません (ここでは、FinalOperation が他の理由でその情報を使用していないと仮定しています)。

説明されているブロックに入る前にトランザクションを開始し、FinalOperation のステータスを確認した後で全体をコミットまたはロールバックします。現在の説明からわかる限り、子操作をネストする必要はありません。

おそらく私は何かが欠けていますか?(以前の/子操作を RETAIN したい場合、それはまったく別のものになることに注意してください...しかし、操作のパッケージ全体をロールバックする最終操作の失敗により、単純なトランザクションが使用可能になります)。

于 2008-10-21T23:00:59.970 に答える