2

更新トランザクションの切り離しの問題に関する質問があります。ここで失われた更新トランザクションの隔離に関する問題の問い合わせ

は、対応する図である。

lost update

と図に伴うテキストを引用する:

Aは、2つのトランザクションがデータ項目を更新してから 両方の場合は、更新が発生した紛失2番目のトランザクションが異常終了し、両方の変更が失われます。 これは同時実行制御を実装していないシステムで発生します。同時実行制御は の同時トランザクションは分離されません。

私の質問は、上図に関連:なぜのTx Aの変更は、のTxのコミットがのTx Bのロールバックの前に発生するという事実を考慮すると失われましたか? (数字はイベントの順序を示します)。

説明できますか?

P.S. Manningが発行したJava Persistence with Hibernate Second Editionの書籍を引用しています。 (参照:https://www.manning.com/books/java-persistence-with-hibernate-second-edition

編集:私はフィギュアと一緒に上記の引用されたテキストが失われた更新の問題を実証するためのものです。したがって、データベースにはほとんど分離がないとみなされ、更新が失われます。私が理解できないのは、図の操作の順序です。つまり、ロールバックの前にコミットが発生した場合は、どこに問題がありますか?ロールバックは考慮されるべきではありません...

答えて

1

答えは、各データベースのトランザクションロギングシステムの実装によって異なります。このようなシステムにはさまざまなタイプがあり、あなたがそのテーマで深く掘り下げたいのであれば、まずこれらのことを詳述する必要があります。

また、回答はどのトランザクション分離レベルが使用されたかによって異なります。ここでも、特定のデータベースだけでなく、データベースの更新に使用された特定の命令にも依存します。いくつかのデータベースでは、同時更新またはロールバックの場合にデータが矛盾する可能性がある場合でも、任意の分離レベルを設定できます。

したがって、特定の実装に関する詳細を提供していないので、抽象データベースがスナップショット分離を使用していると推測できます。つまり、データ変更前、行または行の範囲またはテーブル全体のうち、そのデータのコピーが作成されたことを意味します。コピーは、データを変更する初期状態です。

通常、別のトランザクションが完了しないうちにトランザクションを開始することはできません。その要件はロックによって達成されます。しかし、あなたの例では、1つのトランザクションが正常にデータを変更し、別のトランザクションがロールバックされました。

コミットできないトランザクションは、不完全に変更されたデータを初期状態に戻す必要があります。トランザクションBの場合、分離レベルはスナップショットであるため、状態にはトランザクションAの変更はありません。変更前の初期状態のスナップショットを作成せず、トランザクションログの変更のみを保存し、トランザクションがコミットされたと見なしたときにそれらを適用するデータベースもあります。

これは、トランザクションBの初期状態にトランザクションAの変更がなかったためです。そして、何らかの点では正しいことです:ロールバックは、トランザクションが開始されたときの状態にデータを戻す必要があります。

UPDATE:私たちは抽象プログラミング言語で示された状況を実装した場合

それは次のようになりますどのように?

function Update(rowNumber, data){ 
    initialState = getRowInitialState(rowNumber); // ------- 1 
    operationResult = updateRow(rowNumber, data); 
    if (operationResult == success) 
     commit(rowNumber);      // ---------- 3 
    else 
     rollback(rowNumber, initialState) 
} 

function Delete(rowNumber){ 
    initialState = getRowInitialState(rowNumber); // ---------- 2 
    operationResult = deleteRow(rowNumber); // <--- cause some problems 
    if (operationResult == success) 
     commit(rowNumber); 
    else 
     rollback(rowNumber, initialState)   // -------- 4 
} 

Update(13, "aaaa"); 
Delete(13); 

あなたが見ることができるように、削除操作上のロールバックでは、初期状態にデータをリセットします。トランザクションログがないことを暗示する。通常、データは実際には変更されません。その代わりに、トランザクションログには、何らかの操作を実行し、一部のデータを変更する必要があるという情報が書き込まれます。この場合、ロールバックは実際にUpdate操作の結果を破棄しません。トランザクションログからレコードを削除するだけです。操作が成功した場合、トランザクションログからの変更が実データに適用されます。しかし、抽象データベースにはこのような仕組みがないようです。または、NoSQLデータベースの1つであるトランザクションレスデータベースへのアクセスを示します。この場合、そのようなログはなく、クライアント側で同期を実行する必要があります。

+0

こんにちは@カサンドラッドとあなたの答えはありがとう:私は図と一緒に引用したテキストは、失われた更新の問題を示すためのものです。したがって、データベースにはほとんど分離がないとみなされ、更新が失われます。私が理解できないのは、図の操作の順序です。つまり、ロールバックの前にコミットが発生した場合、問題は何ですか? – balteo

+0

私は数字と引用されたテキストとの間に相違があると感じます...あなたの考えは何ですか? – balteo

+0

より正確には、ロールバックの前にコミットが発生した場合、ロールバックはまったく考慮されるべきではありません。すべき? – balteo

関連する問題