web-dev-qa-db-ja.com

SQL Serverでのネストされたトランザクション

次のシナリオを想像してみてください。

SQL Server 2005を使用しています。他のSQLステートメントの中でも、内部にトランザクションがあるストアドプロシージャを呼び出すトランザクションがあります。外部トランザクションが失敗することがあり、ストアドプロシージャが呼び出されて正常にコミットされた後にロールバックされます。

私の質問は、ストアドプロシージャのトランザクションもロールバックしますか?

35
David Espart

ネストされたトランザクションでは、トップレベルのトランザクションを除いて、コミットは変更をディスクに書き込みません。ただし、ロールバックはトランザクションのレベルに関係なく機能するため、内部トランザクションをロールバックします。

39
Matthew Farwell

もちろん、トップレベルのトランザクションは、コミットまたはロールバックされるまで、すべてのデータ変更を所有します。

ただし、トランザクションモデルについて慎重に検討することをお勧めします。システムにそのようなシナリオが多く存在するほど、ロックの問題にさらされる可能性が高くなります。また、手順の計算コストも増加します。

SQLを合理化するときに、トランザクションが不要な場所に実装されていることがよくあります。私はあなた(そしてトランザクションを扱う誰もが)を各コンテキストでそれらを使用している理由と、トランザクションが実装されなかった場合に何が起こるかについて慎重に考えることをお勧めします。ちょうど私の2cの価値!

9
Timbo

はい、ストアドプロシージャはロールバックされます。

コードの全体的な流れは次のとおりです。

BEGIN TRY

    BEGIN TRANSACTION

    EXEC SotredProcedureName

    --Do some other activity

    COMMIT TRANSACTION
END TRY
BEGIN CATCH

    --IF an error occurs then rollback the current transaction, which includes the stored procedure code.
    ROLLBACK TRANSACTION

END CATCH

乾杯、ジョン

2
John Sansom

ストアドプロシージャ内でbegin tranとcommitを試してみましたが、usp_testと言います。
これらのspを他のクエリで以下のように除外します

update x set name='xxx'
select * from x---contains 'xxx'
begin tran
update x set name='yyy'
select * from x---contains 'yyy'
exec usp_test
select * from x---contains 'zzz' inside the sp
rollback tran

Xテーブルで上記のクエリ名を実行している間は、最初のtranがsp tranコミットでさえロールバックしたため、「xxx」は「zzz」ではありません。
そのため、最初に、データの変更を所有するトランザクションを開始します。

1
Jayaprabha

これは、SQL Serverのトランザクションを理解するときに役立つ記事です。

それは多くの良い例と簡単な定義を提供します。

SQL-Server-Transactions-and-Error-Handling

1
JGilmartin