MySQLモードでサポートされている分離レベル
OceanBaseデータベースは、MySQLモードで以下の4種類の分離レベルをサポートしています:
読み取り未コミット(Read Uncommitted):あるトランザクションが、別のトランザクションによって未コミットのデータを読み取ることができます。トランザクションAがデータ項目を変更したもののまだコミットしていない場合、トランザクションBはその未コミットの変更を即座に確認できます。もしトランザクションAが変更をロールバック(つまり、操作を取り消す)した場合、トランザクションBが読み取ったデータは、以前存在したが現在は存在しない「ダーティ」なデータになります。現在のOceanBaseは、*読み取り未コミット(Read Uncommitted)*分離レベルを構文的にのみサポートしており、ユーザーが読み取り未コミット分離レベルを指定した場合、実際には読み取りコミットが適用されます。
読み取りコミット(Read Committed):あるトランザクションが実行するクエリでは、そのクエリ開始前にコミットされたデータのみを参照できます。読み取りコミットでは、不重复読み取り(不可再現読み取り)や幻読み取りという2つの異常状態を防ぐことはできません。
不重复読み取り(Repeatable Read):トランザクション内で異なる時刻に読み取った同一のデータは一貫しています。
シリアライズ可能(Serializable):この分離レベルは、OracleデータベースのSerializableに類似しており、厳密な意味でのSerializableではありません。
OceanBaseデータベースのデフォルトの分離レベルは**読み取りコミット(Read Committed)**です。
分離レベルの動作比較
MySQLデータベースは読み取り未コミット、読み取りコミット、不重复読み取り、シリアライズ可能の4種類の分離レベルをサポートしていますが、OceanBaseデータベースのMySQLモードは、これら4つの分離レベルにおいて、MySQLデータベースとは一定の相違点があります。
読み取り未コミット: MySQLデータベースは読み取り未コミットをサポートしていますが、OceanBaseデータベースは読み取り未コミットの構文のみをサポートしています。現在のOceanBaseは、*読み取り未コミット(Read Uncommitted)*分離レベルを構文的にのみサポートしており、ユーザーが読み取り未コミット分離レベルを指定した場合、実際には読み取りコミットが適用されます。
読み取りコミット: 読み取りコミット分離レベルで行が更新条件を満たすかどうかを判断する際、MySQLデータベースは半一貫性読み取りを使用します。もし行が並行トランザクションによって更新されている場合、MySQLデータベースは並行トランザクションの終了を待ち、最新バージョンで更新が必要かどうかを判断します。一方、OceanBaseデータベースでは、並行トランザクションが更新しているかどうかに関係なく、常にステートメントスナップショット内のバージョンに基づいて、行が更新条件を満たすかどうかを判断します。
不重复読み取り(Repeatable Read): **不重复読み取り(Repeatable Read)**分離レベルで書き込み競合が発生した場合、MySQLデータベースでは後から書き込むトランザクションは先に書き込むトランザクションの終了を待ちます。先に書き込むトランザクションがロールバックした場合、後から書き込むトランザクションは元のバージョンで直接更新します。先に書き込むトランザクションがコミットした場合、後から書き込むトランザクションは新しくコミットされたバージョンで更新を行います。OceanBaseデータベースでも後から書き込むトランザクションは先に書き込むトランザクションの終了を待ちますが、先に書き込むトランザクションがロールバックした場合、後から書き込むトランザクションは元のバージョンで直接更新します。先に書き込むトランザクションがコミットした場合、後から書き込むトランザクションはロールバックしてエラーを返します。
シリアライズ可能(Serializable): MySQLデータベースの**シリアライズ可能(Serializable)分離レベルは2段階ロック(2PL)を使用し、厳密なシリアライゼーションを保証します。OceanBaseデータベースのシリアライズ可能(Serializable)**分離レベルはスナップショット分離(Snapshot Isolation)を使用し、厳密なシリアライゼーションを保証することはできません。
分離レベルの設定方法
分離レベルの設定には、グローバルレベルとセッションレベルの2つの方法があります。
SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL [READ COMMITTED | REPEATABLE READ | SERIALIZABLE | READ UNCOMMITTED];
分離レベルの使用制限
トランザクションの実行中に分離レベルを設定することは許可されていません。その場合、以下のエラーが発生します:
ERROR 1568 (25001): Transaction characteristics can't be changed while a transaction is in progressグローバルレベルの分離レベルは、セッションレベルの分離レベルによって上書きされる可能性があります。