Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
学ぶ Isolation:リピータブルリードおよびシリアライザブルレベル | セクション
SQL最適化とクエリ機能

bookIsolation:リピータブルリードおよびシリアライザブルレベル

メニューを表示するにはスワイプしてください

Repeatable ReadSerializable の分離レベルの違いを理解することは、特に bank_accountstransfers テーブルのような金融データを扱う場合、SQLトランザクションを運用する上で非常に重要です。両方の分離レベルは、同時実行トランザクションによって発生する特定の異常を防ぐために設計されていますが、それぞれ異なる保証を提供し、パフォーマンスへの影響も異なります。

Repeatable Read では、トランザクション内で一度読み取った行のデータは、同じトランザクション内で再度読み取っても変更されません。他のトランザクションがその行を変更してコミットした場合でも同様です。このレベルは**非再読可能読み取り(non-repeatable reads)を防ぎ、すでにアクセスした行の一貫性を保証します。ただし、Repeatable Read はファントムリード(phantom reads)**を完全には防ぎません。ファントムリードとは、あるトランザクションが条件を満たす行の集合を返すクエリを再実行した際、他のトランザクションによる行の挿入や削除によって、その集合が変化してしまう現象です。

Serializable は最も厳格な分離レベルです。すべてのトランザクションが、まるで一つずつ順番に実行されたかのような結果になるように保証します。このレベルでは、クエリがアクセスするデータ範囲にロックをかけることでファントムリードを防ぎ、他のトランザクションが結果セットに影響を与える行の挿入・更新・削除をブロックします。そのため、Serializable は最高レベルのデータ整合性を提供しますが、ブロッキングが増加し、同時実行性が低下する可能性があります。

bank_accounts テーブルのシナリオを考えてみましょう。あるトランザクションが残高1,000ドル超のすべての口座を読み取っている間に、別のトランザクションが残高2,000ドルの新しい口座を挿入した場合、Repeatable Read では2番目のトランザクションが新しい行を挿入できるため、最初のトランザクション内で同じクエリを再実行するとこの「ファントム」行が見える可能性があります。Serializable では、最初のトランザクションが完了するまで挿入をブロックすることで、これを防ぎます。

12345678910111213141516171819202122232425262728293031323334
-- Transaction 1: Set isolation level to Repeatable Read and read accounts BEGIN; SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; SELECT * FROM bank_accounts WHERE balance > 1000; -- Transaction 2: Insert a new account with balance > 1000 BEGIN; INSERT INTO bank_accounts (owner_name, balance) VALUES ('Frank Miller', 2500.00); COMMIT; -- Transaction 1: Re-run the same SELECT SELECT * FROM bank_accounts WHERE balance > 1000; COMMIT; -- In Repeatable Read, Transaction 1 may see the new row ("phantom read"). -- Now, using Serializable isolation level -- Transaction 1: Set isolation level to Serializable and read accounts BEGIN; SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; SELECT * FROM bank_accounts WHERE balance > 1000; -- Transaction 2: Try to insert a new account with balance > 1000 BEGIN; INSERT INTO bank_accounts (owner_name, balance) VALUES ('George Lucas', 3000.00); -- This operation will block until Transaction 1 commits or rollbacks COMMIT; -- Transaction 1: Re-run the same SELECT SELECT * FROM bank_accounts WHERE balance > 1000; COMMIT; -- In Serializable, Transaction 1 will not see new rows inserted by other transactions until it is finished, preventing phantom reads.
copy

Repeatable ReadSerializable の選択は、アプリケーションの要件や許容できるトレードオフによって決まります。Repeatable Read は、非再読可能読み取りを防ぎたいが、ファントムリードの稀な発生を許容できる場合に適しています。多くのビジネスアプリケーションでは、パフォーマンスや同時実行性を優先するため、この選択が受け入れられることが多いです。Serializable は、絶対的な一貫性と正確性が求められる場合、例えば銀行や金融システムなど、ファントムリードが誤った計算や二重支払いにつながる恐れがある場合に選択します。ただし、Serializable はロックやブロッキングが増加し、スループットが大幅に低下する可能性があるため、その保証が本当に必要な場面に限定して使用すべきです。

1. Repeatable ReadSerializable の主な違いは何ですか?

2. どの分離レベルがファントムリードを防ぎますか?

3. どのような場合に低い分離レベルを選択しますか?

question mark

Repeatable ReadSerializable の主な違いは何ですか?

正しい答えを選んでください

question mark

どの分離レベルがファントムリードを防ぎますか?

正しい答えを選んでください

question mark

どのような場合に低い分離レベルを選択しますか?

正しい答えを選んでください

すべて明確でしたか?

どのように改善できますか?

フィードバックありがとうございます!

セクション 1.  6

AIに質問する

expand

AIに質問する

ChatGPT

何でも質問するか、提案された質問の1つを試してチャットを始めてください

セクション 1.  6
some-alt