1.1 はじめに
そして、トランザクションがどのように機能するかの理論という楽しい作業が始まります。異なるスレッドで同じデータを変更する場合に、システムの動作を維持するにはどうすればよいでしょうか? それとも、あるトランザクションを別のトランザクションで実行したいですか? 私たちはトランザクションの分離を研究することで、これらの質問に対する答えを探し始めます...
トランザクション分離レベルは、 DBMS 内で論理的に並列トランザクションを実行した結果、不整合なデータがどの程度まで許容されるかを決定する条件値です。トランザクション分離レベルのスケールには、最低から最高までランク付けされた多数の値が含まれます。分離レベルが高いほどデータの一貫性が向上しますが、これを使用すると物理的に並列トランザクションの数が減少する可能性があります。
逆に、分離レベルが低いと、より多くの並列トランザクションが可能になりますが、データの精度は低下します。したがって、使用するトランザクション分離レベルを選択することにより、情報システムの開発者は、作業速度とシステムから受信するデータの保証された一貫性の確保の間である程度の選択肢を得ることができます。
トランザクションを使用した同時アクセスの問題
トランザクションが並行して実行される場合、次の問題が発生する可能性があります。
- 更新の損失- 1 つのデータ ブロックが異なるトランザクションによって同時に変更された場合、最後の変更を除くすべての変更が失われます。
- 「ダーティ」読み取り (英語: Dirty read) - トランザクションによって追加または変更されたデータの読み取り。その後確認されません (ロールバック)。
- 非反復読み取り (英語: non-repeatable read) - 同じトランザクション内で再読み取りを行うと、以前に読み取られたデータが変更されます。
- ファントム読み取り- 1 つのトランザクションが実行中に、同じ基準に従って複数の行を選択します。これらのフェッチの間にある別のトランザクションは、行を追加するか、最初のトランザクションのフェッチ基準で使用された一部の行の列を変更し、正常に終了します。その結果、最初のトランザクションで同じ選択を行っても、異なる行セットが得られることがわかります。
これらの問題が発生する可能性がある状況を検討してください。
1.2 アップデートが失われた
1 つのデータ ブロックが異なるトランザクションによって同時に変更されたときに、変更の 1 つが失われる状況。
2 つのトランザクションが同時に実行されているとします。
トランザクション 1 | トランザクション 2 |
---|---|
UPDATE tbl1 SET f2=f2+20 WHERE f1=1; | UPDATE tbl1 SET f2=f2+25 WHERE f1=1; |
どちらのトランザクションでも、f2 フィールドの値が変更されます。完了すると、フィールドの値は 45 増加する必要があります。実際には、次の一連のアクションが発生する可能性があります。
- 両方のトランザクションは同時にフィールドの現在の状態を読み取ります。ここでは厳密な物理的同時実行性は必要ありません。別のトランザクションが結果を書き込む前に、順番に 2 番目の読み取り操作が完了するだけで十分です。
- どちらのトランザクションも、以前に読み取られた値にそれぞれ 20 と 25 を加算して、新しいフィールド値を計算します。
- トランザクションは計算結果をフィールド f2 に書き込もうとします。2 つの書き込みを同時に実行することは物理的に不可能であるため、実際には、書き込み操作の一方が先に実行され、もう一方が後に実行されます。2 回目の書き込み操作では、最初の書き込み操作の結果が上書きされます。
その結果、両方のトランザクションが完了すると、f2 フィールドの値は 45 ではなく 20 または 25 増加する可能性があります。つまり、データ変更トランザクションの 1 つが「消滅」します。
1.3 「ダーティ」な読み取り
後でコミット (ロールバック) に失敗するトランザクションによって追加または変更されたデータの読み取り。
次の SQL ステートメントを実行する異なるアプリケーションによって開かれた 2 つのトランザクションがあるとします。
トランザクション 1 | トランザクション 2 |
---|---|
UPDATE tbl1 SET f2=f2+1 WHERE f1=1; | |
SELECT f2 FROM tbl1 WHERE f1=1; | |
ロールバック作業。 |
トランザクション 1 でフィールド f2 の値が変更され、トランザクション 2 でこのフィールドの値が選択されます。その後、トランザクション 1 がロールバックされるため、2 番目のトランザクションで受け取った値はデータベースに格納されている値と異なります。
1.4 反復不可能な読み取り
同じトランザクション内で再読み取りを行うと、以前に読み取られたデータが変更されていることが判明する状況。
次の SQL ステートメントを実行する異なるアプリケーションによって開かれた 2 つのトランザクションがあるとします。
トランザクション 1 | トランザクション 2 |
---|---|
SELECT f2 FROM tbl1 WHERE f1=1; | |
UPDATE tbl1 SET f2=f2+3 WHERE f1=1; | |
専念; | |
SELECT f2 FROM tbl1 WHERE f1=1; |
トランザクション 2 でフィールド f2 の値が選択され、トランザクション 1 でフィールド f2 の値が変更されます。トランザクション 2 でフィールド f2 から値を再度選択しようとすると、異なる結果が得られます。この状況は、データを部分的に変更してデータベースに書き戻すために読み取られる場合に特に容認できません。
1.5 「ファントム」を読む
同じトランザクション内で繰り返し読み取り中に、同じ選択によって異なる行セットが与えられる状況。
次の SQL ステートメントを実行する異なるアプリケーションによって開かれた 2 つのトランザクションがあるとします。
トランザクション 1 | トランザクション 2 |
---|---|
tbl1 から SUM(f2) を選択します。 | |
tbl1 (f1,f2) VALUES(15,20) に挿入します。 | |
専念; | |
tbl1 から SUM(f2) を選択します。 |
トランザクション 2 は、フィールド f2 のすべての値を使用する SQL ステートメントを実行します。次に、トランザクション 1 に新しい行が挿入され、トランザクション 2 で SQL ステートメントが再実行されると、異なる結果が生成されます。このような状況をファントムリーディング(ファントムリーディング)といいます。これは、繰り返しデータアクセスの結果がデータ自体の変更/削除によって変化するのではなく、新しい (ファントム) データの出現によって変化するという点で、繰り返し不可能な読み取りとは異なります。
GO TO FULL VERSION