2

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 がどの具体的な条件に一致するかということです。

どうもありがとう!

4

1 に答える 1

2

ロールバックは、DBではなく、常にクライアント アプリケーションで処理する必要があります。クライアントは、単一の「作業単位」として多くの異なる操作を実行している可能性があるため、クライアントは、その作業がいつデータベースにコミットされるか、またはロールバックされるかを制御する必要があります。


Tom Kyte からのこの役立つリンクを参照できます。Tom Kyte は、この問題について非常に強く感じているため、PL/SQL からコミット/ロールバックを削除することさえ提案しています (Oracle の手続き型言語。DB が mysql であることは知っていますが、概念は同じままです)。 .

トランザクション フローを実際に制御できる唯一のものであるクライアント アプリケーションのもう 1 つの説得力のある理由は、次のいずれかです。

a) コミットまたは b) ロールバック

その仕事。(トリガー、自律型トランザクション、およびその他の場合に加えて、自分のやり方があれば、plsqlでコミットとロールバックを廃止します:)

于 2010-07-23T10:46:12.723 に答える