データベーストランザクションを操作する場合、トランザクション内のすべてのステートメントがすでに問題なく実行されていると仮定して、トランザクションの最後のCOMMIT
ステートメントが失敗する可能性のある条件(ある場合)は何ですか?
たとえば...いくつかの 2フェーズ または フェーズコミットプロトコル があるとしましょう。ここで一連のステートメントを実行し、マスタープロセスから通知されるのを待ちます。最終的にトランザクションをコミットしても問題がない場合:
-- <initial handshaking stuff>
START TRANSACTION;
-- <Execute a bunch of SQL statements>
-- <Inform master of readiness to commit>
-- <Time passes... background transactions happening while we wait>
-- <Receive approval to commit from master (finally!)>
COMMIT;
コードがその最後のCOMMITステートメントに到達してDBMSに送信した場合、そのステートメントでエラー(一意性の問題、データベースがいっぱいなど)が発生する可能性はありますか?どのようなエラーですか?どうして?それらはどのように表示されますか?実行するDBMSによって異なりますか?
COMMITは失敗する可能性があります。実行したいすべての変更をログに記録するのに十分なリソースがあったかもしれませんが、実際に変更を実装するためのリソースが不足しています。
そして、それは失敗するかもしれない他の理由を考慮していません:
変更自体がデータベースの制約に適合しない場合があります。
停電は物事が完了するのを止めます。
要求された選択の同時実行性のレベルにより、更新が許可されない場合があります(たとえば、変更されたテーブルを更新するカーソル)。
コミットがタイムアウトするか、飢餓の問題が原因でタイムアウトする接続になっている可能性があります。
クライアントとデータベース間のネットワーク接続が失われる可能性があります。
そして、私の頭のてっぺんにない他のすべての「単純な」理由。
一部のデータベースエンジンでは、COMMITまでUNIQUEインデックス制約チェックを延期することができます。明らかに、コミット時に制約が当てはまらない場合は失敗します。
承知しました。
マルチユーザー環境では、他のユーザーによる変更が原因でCOMMITが失敗する場合があります(たとえば、COMMITを現在のデータベースに適用すると、参照制約に違反します...)。
トーマス
2フェーズコミットを使用している場合は、いいえ。うまくいかない可能性のあるものはすべて、準備段階で行われます。
コミット中にネットワークの停止、電力の低下、宇宙線などが発生する可能性がありますが、それでもトランザクションは永続ストレージに書き込まれ、コミットがトリガーされた場合は、リカバリプロセスがそれらを実行する必要があります。
うまくいけば。
確かに、いくつかの問題がある可能性があります。コミットする行為は、それ自体で、トランザクションがコミットされたことを示すために、最終的な永続的なエントリを作成する必要があります。そのエントリの作成が失敗した場合、トランザクションはコミットできません。
Ignacioが述べているように、遅延制約チェックが存在する可能性があります(これは、DBMSエンジンに応じて、一意の制約だけでなく、任意の形式の制約になります)。
SQL Server固有:FILESTREAMデータのフラッシュは、コミット時まで延期できます。それは失敗する可能性があります。
非常に単純で見過ごされがちな項目の1つは、ハードウェア障害です。基盤となるサーバーが停止すると、コミットが失敗する可能性があります。これは、ディスク、CPU、メモリ、さらにはネットワークに関連している可能性があります。
マスターから承認を受け取らない場合、トランザクションは失敗する可能性があります(さまざまな理由で)。
システムがどんなに素晴らしく設計されていても、コミットが成功したかどうかを知ることができない状況に陥る可能性があります。場合によっては、問題にならないこともあります(たとえば、データベースを保持しているハードドライブがスラグの山に変わった場合、コミットが成功する前にコミットが成功したかどうかを判断できない場合がありますが、実際には問題ではありません)。ただし、他の場合には、これが問題になる可能性があります。特に分散データベースシステムでは、コミット中の適切なタイミングで接続障害が発生した場合、相手側がコミットまたはロールバックを予期しているかどうかを双方が確認することは不可能です。