特定の状況下で、実行したすべてを元に戻してエラーコードを呼び出し元に返すか、受け入れ/コミットして成功を呼び出し元に返すことができるように、セーブポイントを設定する必要があるストアドプロシージャがあります。しかし、発信者がすでにトランザクションを開始しているかどうかに関係なく、動作する必要があります。ドキュメントは、このテーマに関して非常に混乱しています。これがうまくいくと思うことですが、すべての影響については確信がありません。
問題は、これStored Procedure (SP)
は他の人から呼ばれているということです。そのため、ユーザーがトランザクションを開始したかどうかはわかりません...ユーザーにSPを使用するためにトランザクションを開始するように要求した場合でも、Save Points
...の適切な使用について質問があります。
私のSPは、トランザクションが進行中であるかどうかをテストし、進行中でない場合は、で開始しBEGIN TRANSACTION
ます。トランザクションがすでに進行中の場合は、代わりに、を使用して保存ポイントを作成し、SAVE TRANSACTION MySavePointName
これが私が行ったことであるという事実を保存します。
次に、変更をロールバックする必要がある場合、BEGIN TRANSACTION
以前に行った場合は、ロールバックしますROLLBACK TRANSACTION
。セーブポイントを実行した場合は、実行しますROLLBACK TRANSACTION MySavePointName
。このシナリオはうまく機能しているようです。
ここで少し混乱します。これまでに行った作業を維持したい場合は、トランザクションを開始した場合に実行しCOMMIT TRANSACTION
ます。しかし、セーブポイントを作成した場合はどうなりますか?試しCOMMIT TRANSACTION MySavePointName
ましたが、呼び出し元がトランザクションをコミットしようとしてエラーが発生します。
COMMIT TRANSACTION要求には、対応するBEGINTRANSACTIONがありません。
だから私は疑問に思っています-セーブポイントはロールバックできます(それは機能します:ROLLBACK TRANSACTION MySavePointName
呼び出し元のトランザクションをロールバックしません)。しかし、おそらくそれを「コミット」する必要はないのでしょうか。ロールバックする必要がある場合に備えて、そのまま残りますが、元のトランザクションがコミット(またはロールバック)されると消えますか?
トランザクションを「ネスト」する「より良い」方法がある場合は、同様にいくつかの光を当ててください。ネストする方法がわかりませんがBEGIN TRANSACTION
、内部トランザクションをロールバックまたはコミットするだけです。単にデクリメントしROLLBACK
ながら、常に最上位のトランザクションにロールバックするようです。COMMIT
@@trancount