1

私はしばらくの間、これを機能させようとしてきました。

SPAデータベースに複数の挿入を行う別の開発者によって作成されたストアド プロシージャ (と呼びます) があり、それらの挿入はすべてストアド プロシージャのトランザクション内にラップされています。トランザクションを使用しない別のストアド プロシージャもあります (それを呼び出しますSPB)。

私の .NET コードから、これらのストアド プロシージャの両方をトランザクションでラップし、SPB成功しない場合はすべてSPAがロールバックされるようにする必要があります。残念ながら、これは私にはうまくいきません。私が得るエラーは次のとおりです。

SALE をロールバックできません。その名前のトランザクションまたはセーブポイントは見つかりませんでした。
EXECUTE 後のトランザクション数は、BEGIN ステートメントと COMMIT ステートメントの数が一致していないことを示しています。前のカウント = 1、現在のカウント = 2。

ROLLBACKorが終了する前にCOMMIT常に内部で呼び出されていることを確認しました。SPA私の .NET コードは非常に単純です。

try {
    conn.Open();
    trans = conn.BeginTransaction();
    prod.Connection = conn;
    prod.Transaction = trans;

    // Execute SPA
    // Execute SPB

} catch (Exception ex) {
    trans.Rollback();
} finally {
    conn.Close();
}

方程式から .NET を取り出し、単純に SSMS を使用して SP をラップすると、同じエラー メッセージが表示されます。

BEGIN TRAN
DECLARE @return_value int
EXEC    @return_value = [dbo].[spSPA] [...]
SELECT  'Return Value' = @return_value
COMMIT TRAN

何か案は?

編集:

SPA次のようになります。

BEGIN TRY
BEGIN TRAN SALE

IF SomeCondition
  DoSomething
ELSE
  ROLLBACK TRAN SALE
  RETURN 100

IF SomeCondition
  DoSomething
ELSE
  ROLLBACK TRAN SALE
  RETURN 200

...

COMMIT TRAN SALE
RETURN 0

END TRY
BEGIN CATCH
  IF XACT_STATE() <> 0
    ROLLBACK TRAN SALE
END CATCH
4

1 に答える 1

1

私はついに私の問題を発見しました。Cannot roll back SALE. No transaction or savepoint of that name was found.ネストされたトランザクションがある場合、ロールバック時に最も外側のトランザクションの名前を指定する必要があるため、警告が表示されます。もちろん、そのトランザクションの名前はわかりません。

回避策は、 TechNetで説明されているようなセーブポイントを使用することです。したがって、既存のトランザクションがあるかどうかを確認し、存在する場合はセーブポイントを使用する必要があります。それ以外の場合は、独自に作成します。

DECLARE @TRANCOUNT int
SET @TRANCOUNT = @@TRANCOUNT

IF @TRANCOUNT = 0 BEGIN TRAN
ELSE SAVE TRANSACTION SALE
于 2013-11-15T17:25:10.187 に答える