トランザクション - 分離レベル

 クラウディア
1. 概要
2. レベル
3. 参照
4. 設定

1. 概要

 トランザクションには、分離レベルという概念が存在します。  で、これは、参考サイトによれば、「ANSI/ISO SQL標準」で定められているそうなので、データベースの種類によらず、一般的に存在するということですな。  本ページは、下記のサイトを参考にさせていただきました。
トランザクション分離レベルについてのまとめ #MySQL」
「トランザクション分離レベル - Wikipedia

2. レベル

 分離レベルは、4段階だそうで、それを、ゆるい順に表記すると。
レベル 簡単に言うと 詳しく言うと 備考
READ UNCOMMITTED 確定していないデータまで読み取る 複数の並行に動作するトランザクションそれぞれの結果が、いかなる場合でも、それらのトランザクションを時間的重なりなく逐次実行した場合と同じ結果となる。このような性質を直列化可能性(Serializability)と呼ぶ.SERIALIZABLEは最も強い分離レベルであり、最も安全にデータを操作できるが、相対的に性能は低い。ただし同じ結果とされる逐次実行の順はトランザクション処理のレベルでは保証されない。
READ COMMITTED 確定した最新データを常に読み取る ひとつのトランザクションが実行中の間、読み取り対象のデータが途中で他のトランザクションによって変更される心配はない。同じトランザクション中では同じデータは何度読み取りしても毎回同じ値を読むことができる。
ただし ファントム・リード(Phantom Read) と呼ばれる現象が発生する可能性がある。ファントム・リードでは、並行して動作する他のトランザクションが追加したり削除したデータが途中で見えてしまうため、処理の結果が変わってしまう。
REPEATABLE READ 読み取り対象のデータを常に読み取る 他のトランザクションによる更新については、常にコミット済みのデータのみを読み取る。 MVCC はREAD COMMITTEDを実現する実装の一つである。 ファントム・リード に加え、非再現リード(Non-Repeatable Read)と呼ばれる、同じトランザクション中でも同じデータを読み込むたびに値が変わってしまう現象が発生する可能性がある。
SERIALIZABLE 直列化可能??? 他の処理によって行われている、書きかけのデータまで読み取る。 PHANTOM 、 NON-REPEATABLE READ 、さらに ダーティ・リード(Dirty Read) と呼ばれる現象(不完全なデータや、計算途中のデータを読み取ってしまう動作)が発生する。トランザクションの並行動作によってデータを破壊する可能性は高いが、その分性能は高い。

 「Wikipedia」の記述をまんま転記しているので、わたしが理解できているわけではありません。
 とりあえず、「SERIALIZABLE」が、一番安全なようなので、「SERIALIZABLE」にしちゃえばいいじゃんと思いがちでありますが。
 複数のプロセスが平行で動作している場合、「SERIALIZABLE」だと、やたら待ちが発生したりするちゅうことのようです。

3. 参照

 現在の、分離レベルを見るには・・・。  これは、本来、「データベース - SQL 構文」に書くべきなのかもしれませんが。  「IBM DB2」で、一発でこれを参照する方法が・・・わかりません。  「PostgreSQL」は、構文があります。

SHOW transaction isolation level;
 なんの指定も、していなかったのですが・・・。

 transaction_isolation
-----------------------
 read committed
(1 行)
 思うに、デフォルトでは、2番目に緩いレベルになっているということね。

4. 設定

 これも、今んとこ(2024年7月8日)、「PostgreSQL」しか、わからない。

SET TRANSACTION ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED } READ WRITE | READ ONLY;
 他にも細かくあるのですが、大ざっぱにこれ。  「{}」内は、分離レベルのどれかで、それに続くのが、読み書きか、読み込みのみ、ちゅうことですな。  ちょっと、やってみました。  「psql」を起動して。

feed=# BEGIN;
BEGIN
feed=# SET TRANSACTION ISOLATION LEVEL SERIALIZABLE READ WRITE;
SET
feed=# SHOW transaction isolation level;
 transaction_isolation
-----------------------
 serializable
(1 行)
 間違えて、「BEGIN」の前に、「SET TRANSACTION」しようとしたら。

feed=# SET TRANSACTION ISOLATION LEVEL SERIALIZABLE READ WRITE;
WARNING:  SET TRANSACTION can only be used in transaction blocks
SET
 と、言われまして。  「BEGIN」でトランザクションを開始しないと、分離レベルを変えても意味がないらしい。
ハイスピードプラン