MySql InnoDB は自動コミットをオフに設定し、デフォルトの分離レベル REPEATABLE READ を使用します。2 つの異なるトランザクション T1 と T2 が時系列で実行されるシナリオが 2 つあります。
1)
time T1 T2
t1 update row 1->OK
t2 update row 2->OK
t3 update row 2->wait->timeout error
t4 commit or rollback or retry t3
T1 は、T2 がまだ解放していない行 2 の書き込みロックを取得できないため、t3 でタイムアウト エラーを取得します。ただし、T1 が t4 でコミットすると、T1 の「部分的な」更新につながります。つまり、行 1 は更新されますが、行2 そうではないため、ACID の「原子性」規則は、この慣行によって違反されます。
ACID の「原子性」ルールによれば、トランザクションは「完了する」か失敗する必要がありますが、部分的ではありません。
APP は、T1 にロールバックを要求するか、t3 でエラーを受信して t4 でコミットする前に、成功するまでタイムアウトした更新を再試行する必要があります。これにより、アトミシティ ルールが達成されます。
2)
time T1 T2
t1 update row 1->OK
t2 update row 2->OK
t3 update row 2->wait
t4 update row 1-> DB detects deadlock then forces T2 rolled back
wait->OK
1) DB はタイムアウト エラーを APP に配信するだけであり、T1 をロールバックするかどうかを決定するのは APP 次第ですが、2) DB はデッドロック エラーを検出するだけでなく、デッドロックになる可能性のある T2 をロールバックするように動作します。
理論的には、1) DB は T1 をロールバックするように動作することもできますが、2) DB はデッドロックを引き起こす操作をキャンセルしてデッドロック エラーを APP に送信するだけで、T2 をロールバックするかどうかを決定するのは APP 次第です。
問題は、最初に DB レベルでエラーが検出されたときに、APP またはそれ自体がロールバックを処理する必要があるかどうかを選択するために、DB がどの具体的な条件に一致するかということです。
どうもありがとう!