トランザクションでストアド プロシージャの呼び出しをラップし、分離レベルを指定できます。
または、ストアド プロシージャ内にトランザクションを配置して、そこで分離レベルを指定することもできます。
どちらにするのが良いですか?
トランザクションでストアド プロシージャの呼び出しをラップし、分離レベルを指定できます。
または、ストアド プロシージャ内にトランザクションを配置して、そこで分離レベルを指定することもできます。
どちらにするのが良いですか?
私の意見では、ストアドプロシージャの内部が最も適切な場所です。
優れたトランザクション設計の基本的なルールの1つは、トランザクションの存続期間をできるだけ短くすることです。そのため、トランザクションロジックが完了した直後にコミットを実行する必要があります。ストアドプロシージャの外部でトランザクションを制御すると、トランザクションの寿命が不必要に長くなります。
また、プロシージャ内でトランザクションを定義すると、コードがより明確になることも考慮する必要があります。そうしないと、別のコーダーが特定のストアドプロシージャを変更する必要がある場合、呼び出し元が実際にプロシージャをトランザクションでラップするという事実に依存する必要があります。プロシージャ内にトランザクションを含めると、トランザクション処理が明示的に定義されます。
一貫したアプローチを採用する必要があります。ストアド プロシージャ内でトランザクションをロールバックすると、ネストされたトランザクション スコープ (スコープ外を含む) がロールバックされることに注意してください。
取引は手続き外にとどめておくことをお勧めします。そうすれば、完全なコントロールを維持できます。
参考までに、Oracle はネストされたトランザクションをサポートしていません。外部レベルでトランザクションを開始し、一連のストアド プロシージャを呼び出すと、コミットを発行するストアド プロシージャはトランザクション全体をコミットします。それが引き起こした取引。したがって、C# などの言語から呼び出す場合は、ストアド プロシージャの外部でトランザクションを管理する必要があります。
比較のために、興味があるかもしれないと思っただけです。
データベースAPIの外部、または少なくとも外部層。
すべてのストアドプロシージャ内でコミットする場合は、自動コミットをオンにすることもできます。次のストアドプロシージャのイメージを作成してください。
create_user_with_email_address
calls -> create_user
calls -> create_email_address
create_user / create_email_address内でコミットした場合、create_user_with_email_addressはトランザクションになりません。create_email_addressが失敗した場合、create_userはすでにコミットされており、データが壊れています。
トランザクションを必要なだけ高くして、すべてをその中に保持します。
ビジネス ロジックに依存します。SP がアトミックである場合は、独自のトランザクションを実装する必要があります。そうしないと、将来的に誤ったコードがラッピング トランザクションを作成しないというリスクを冒すことになります。あなたの質問への回答として、トランザクションは SP 内に移動する必要があると思います。
もちろん、両方を行うのを止めるものは何もありません。アトミック SP は独自のトランザクションを実装し、その範囲外に他のより広範なトランザクションが既に存在している可能性があります。
一般に、SP 内でトランザクションを使用して作成する場合、既にトランザクション スコープ内にいる可能性があるため、コミット/ロールバックを実行するときにこのインスタンスをコーディングする必要があります。
Sproc 内で次のことを行います。これは、単にロールバックすると、外側の SProc のトランザクション カウントが台無しになり、アプリケーションに警告が返される可能性があるためです。また、期待/処理されていない場合は、アプリケーション エラーが発生する可能性があります。 .
ただし、このメソッドは「ローカル」トランザクションのみをロールバックするため、外部の「呼び出し元」は戻り値を適切に解釈する必要があります。代わりに RAISERROR などを使用してください。
BEGIN TRANSACTION MySprocName_01
SAVE TRANSACTION MySprocName_02
...
IF @ErrorFlag = 0
BEGIN
COMMIT TRANSACTION MySprocName_01
END
ELSE
BEGIN
ROLLBACK TRANSACTION MySprocName_02
COMMIT TRANSACTION MySprocName_01
END