Babelfish と SQL Server の分離レベルの比較 - Amazon Aurora

Babelfish と SQL Server の分離レベルの比較

以下は、SQL Server と Babelfish が ANSI 分離レベルを実装する方法に関するニュアンスの例です。

注記
  • Babelfish では、分離レベル Repeatable Read とスナップショットは同じです。

  • Babelfish では、Read Uncommitted と Read Committed は同じです。

次の例は、以下で説明するすべての例においてベーステーブルを作成する方法を示しています。

CREATE TABLE employee ( id sys.INT NOT NULL PRIMARY KEY, name sys.VARCHAR(255)NOT NULL, age sys.INT NOT NULL ); INSERT INTO employee (id, name, age) VALUES (1, 'A', 10); INSERT INTO employee (id, name, age) VALUES (2, 'B', 20); INSERT INTO employee (id, name, age) VALUES (3, 'C', 30);

BABELFISH READ UNCOMMITTED と SQL SERVER READ UNCOMMITTED 分離レベルの比較

SQL SERVER の DIRTY READS
トランザクション 1 トランザクション 2 SQL Server Read Uncommitted Babelfish Read Uncommitted

BEGIN TRANSACTION

BEGIN TRANSACTION

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

UPDATE employee SET age=0;

更新に成功。

更新に成功。

INSERT INTO employee VALUES (4, 'D', 40);

挿入に成功。

挿入に成功。

SELECT * FROM employee;

トランザクション 1 では、トランザクション 2 からのコミットされていない変更が表示されます。

Babelfish での Read Committed と同じです。トランザクション 2 からのコミットされていない変更は、トランザクション 1 には表示されません。

COMMIT

SELECT * FROM employee;

トランザクション 2 によってコミットされた変更が表示されます。

トランザクション 2 によってコミットされた変更が表示されます。

BABELFISH READ COMMITTED と SQL SERVER READ COMMITTED 分離レベルの比較

READ - WRITE BLOCKING
トランザクション 1 トランザクション 2 SQL Server Read Committed Babelfish Read Committed

BEGIN TRANSACTION

BEGIN TRANSACTION

SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

SELECT * FROM employee;

UPDATE employee SET age=100 WHERE id = 1;

更新に成功。

更新に成功。

UPDATE employee SET age = 0 WHERE age IN (SELECT MAX(age) FROM employee);

トランザクション 2 がコミットされるまでステップがブロックされます。

トランザクション 2 の変更はまだ表示されていません。Updates row with id=3.

COMMIT

トランザクション 2 は正常にコミットされます。トランザクション 1 はブロック解除され、トランザクション 2 からの更新が表示されます。

トランザクション 2 は正常にコミットされます。

SELECT * FROM employee;

トランザクション 1 は id = 1 で行を更新します。

トランザクション 1 は id = 3 で行を更新します。

BABELFISH READ COMMITTED と SQL SERVER READ COMMITTED スナップショット分離レベルの比較

新しく挿入された行のブロック動作
トランザクション 1 トランザクション 2 SQL Server Read Committed スナップショット Babelfish Read Committed

BEGIN TRANSACTION

BEGIN TRANSACTION

SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

INSERT INTO employee VALUES (4, 'D', 40);

UPDATE employee SET age = 99;

トランザクション 1 がコミットされるまでステップがブロックされます。挿入された行はトランザクション 1 によってロックされます。

3 行を更新しました。新しく挿入された行はまだ表示されません。

COMMIT

コミットは成功しました。トランザクション 2 のブロックが解除されました。

コミットは成功しました。

SELECT * FROM employee;

All 4 rows have age=99.

id = 4 の行は、更新クエリ中にトランザクション 2 に表示されなかったため、保持時間の値は 40 です。その他の行は age=99 に更新されます。

BABELFISH REPEATABLE READ と SQL SERVER REPEATABLE READ 分離レベルの比較

読み取り/書き込みブロック動作
トランザクション 1 トランザクション 2 SQL Server Repeatable Read Babelfish Repeatable Read

BEGIN TRANSACTION

BEGIN TRANSACTION

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;

SELECT * FROM employee;

UPDATE employee SET name='A_TXN1' WHERE id=1;

SELECT * FROM employee WHERE id != 1;

SELECT * FROM employee;

トランザクション 2 はトランザクション 1 がコミットされるまでブロックされます。

トランザクション 2 は正常に進みます。

COMMIT

SELECT * FROM employee;

トランザクション 1 からの更新が表示されます。

トランザクション 1 からの更新が表示されません。

COMMIT

SELECT * FROM employee;

トランザクション 1 からの更新が表示されます。

トランザクション 1 からの更新が表示されます。

書き込み/書き込みブロック動作
トランザクション 1 トランザクション 2 SQL Server Repeatable Read Babelfish Repeatable Read

BEGIN TRANSACTION

BEGIN TRANSACTION

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;

UPDATE employee SET name='A_TXN1' WHERE id=1;

UPDATE employee SET name='A_TXN2' WHERE id=1;

トランザクション 2 がブロックされました。

トランザクション 2 がブロックされました。

COMMIT

コミットが成功し、トランザクション 2 のブロックが解除されました。

コミットが成功し、トランザクション 2 がエラーで失敗し、同時更新によりアクセスをシリアル化できませんでした。

COMMIT

コミットは成功しました。

トランザクション 2 はすでに中止されています。

SELECT * FROM employee;

id=1 の行に name='A_TX2' があります。

id=1 の行に name='A_TX1' があります。

PHANTOM READ
トランザクション 1 トランザクション 2 SQL Server Repeatable Read Babelfish Repeatable Read

BEGIN TRANSACTION

BEGIN TRANSACTION

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;

SELECT * FROM employee;

INSERT INTO employee VALUES (4, 'NewRowName', 20);

トランザクション 2 はブロッキングなしで進行します。

トランザクション 2 はブロッキングなしで進行します。

SELECT * FROM employee;

新しく挿入された行が表示されます。

新しく挿入された行が表示されます。

COMMIT

SELECT * FROM employee;

トランザクション 2 によって挿入された新しい行が表示されます。

トランザクション 2 によって挿入された新しい行が表示されません。

COMMIT

SELECT * FROM employee;

新しく挿入された行が表示されます。

新しく挿入された行が表示されます。

さまざまな最終結果
トランザクション 1 トランザクション 2 SQL Server Repeatable Read Babelfish Repeatable Read

BEGIN TRANSACTION

BEGIN TRANSACTION

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;

UPDATE employee SET age = 100 WHERE age IN (SELECT MIN(age) FROM employee);

トランザクション 1 は id 1 で行を更新します。

トランザクション 1 は id 1 で行を更新します。

UPDATE employee SET age = 0 WHERE age IN (SELECT MAX(age) FROM employee);

SELECT ステートメントはトランザクション 1 の UPDATE クエリによってロックされた行の読み取りを試みるため、トランザクション 2 はブロックされます。

読み取りがブロックされないため、トランザクション 2 はブロックなしで進行します。SELECT ステートメントが実行され、トランザクション 1 の変更がまだ表示されないため、id = 3 の行が最終的に更新されます。

SELECT * FROM employee;

このステップは、トランザクション 1 がコミットされた後に実行されます。id = 1 の行は、前のステップでトランザクション 2 によって更新され、ここに表示されます。

id = 3 の行はトランザクション 2 によって更新されます。

COMMIT

トランザクション 2 のブロックが解除されました。

コミットは成功しました。

COMMIT

SELECT * FROM employee;

どちらのトランザクションも、id = 1 の行で更新されます。

トランザクション 1 と 2 によって異なる行が更新されます。

BABELFISH SERIALIZABLE と SQL SERVER SERIALIZABLE 分離レベルの比較

SQL SERVER の範囲ロック
トランザクション 1 トランザクション 2 SQL Server Serializable Babelfish Serializable

BEGIN TRANSACTION

BEGIN TRANSACTION

SET TRANSACTION ISOLATION LEVEL SERILAIZABLE;

SET TRANSACTION ISOLATION LEVEL SERILAIZABLE;

SELECT * FROM employee;

INSERT INTO employee VALUES (4, 'D', 35);

トランザクション 2 はトランザクション 1 がコミットされるまでブロックされます。

トランザクション 2 はブロッキングなしで進行します。

SELECT * FROM employee;

COMMIT

トランザクション 1 は正常にコミットされます。トランザクション 2 のブロックが解除されました。

トランザクション 1 は正常にコミットされます。

COMMIT

SELECT * FROM employee;

新しく挿入された行が表示されます。

新しく挿入された行が表示されます。

さまざまな最終結果
トランザクション 1 トランザクション 2 SQL Server Serializable Babelfish Serializable

BEGIN TRANSACTION

BEGIN TRANSACTION

SET TRANSACTION ISOLATION LEVEL SERILAIZABLE;

SET TRANSACTION ISOLATION LEVEL SERILAIZABLE;

INSERT INTO employee VALUES (4, 'D', 40);

UPDATE employee SET age =99 WHERE id = 4;

トランザクション 1 はトランザクション 2 がコミットされるまでブロックされます。

トランザクション 1 はブロッキングなしで進行します。

COMMIT

トランザクション 2 は正常にコミットされます。トランザクション 1 のブロックが解除されました。

トランザクション 2 は正常にコミットされます。

COMMIT

SELECT * FROM employee;

新しく挿入された行は、保持時間の値 = 99 で表示されます。

新しく挿入された行は、保持時間の値 = 40 で表示されます。

一意の制約でのテーブルへの挿入
トランザクション 1 トランザクション 2 SQL Server Serializable Babelfish Serializable

BEGIN TRANSACTION

BEGIN TRANSACTION

SET TRANSACTION ISOLATION LEVEL SERILAIZABLE;

SET TRANSACTION ISOLATION LEVEL SERILAIZABLE;

INSERT INTO employee VALUES (4, 'D', 40);

INSERT INTO employee VALUES ((SELECT MAX(id)+1 FROM employee), 'E', 50);

トランザクション 1 はトランザクション 2 がコミットされるまでブロックされます。

トランザクション 1 はトランザクション 2 がコミットされるまでブロックされます。

COMMIT

トランザクション 2 は正常にコミットされます。トランザクション 1 のブロックが解除されました。

トランザクション 2 は正常にコミットされます。エラー重複キー値で中止されたトランザクション 1 は、一意の制約に違反します。

COMMIT

トランザクション 1 は正常にコミットされます。

トランザクション 1 のコミットは失敗し、トランザクション間の読み取り/書き込み依存関係によりアクセスをシリアル化できませんでした。

SELECT * FROM employee;

行 (5, 'E', 50) が挿入されます。

4 行のみ存在します。

Babelfish では、分離レベルでシリアル化可能な同時トランザクションは、これらのトランザクションの実行がそれらのトランザクションの可能なすべてのシリアル (一度に 1 つ) 実行と一致しない場合、シリアル化異常エラーで失敗します。

シリアル化異常
トランザクション 1 トランザクション 2 SQL Server Serializable Babelfish Serializable

BEGIN TRANSACTION

BEGIN TRANSACTION

SET TRANSACTION ISOLATION LEVEL SERILAIZABLE;

SET TRANSACTION ISOLATION LEVEL SERILAIZABLE;

SELECT * FROM employee;

UPDATE employee SET age=5 WHERE age=10;

SELECT * FROM employee;

トランザクション 2 はトランザクション 1 がコミットされるまでブロックされます。

トランザクション 2 はブロッキングなしで進行します。

UPDATE employee SET age=35 WHERE age=30;

COMMIT

トランザクション 1 は正常にコミットされます。

トランザクション 1 は最初にコミットされ、正常にコミットできます。

COMMIT

トランザクション 2 は正常にコミットされます。

トランザクション 2 のコミットはシリアル化エラーで失敗し、トランザクション全体がロールバックされました。トランザクション 2 を再試行します。

SELECT * FROM employee;

両方のトランザクションからの変更が表示されます。

トランザクション 2 はロールバックされました。トランザクション 1 の変更のみが表示されます。

Babelfish では、すべての同時トランザクションが分離レベル SERIALIZABLE で実行されている場合にのみ、シリアル化異常が発生する可能性があります。例えば、上記の例で、代わりにトランザクション 2 を分離レベル REPEATABLE READ に設定するとします。

トランザクション 1 トランザクション 2 SQL Server 分離レベル Babelfish 分離レベル

BEGIN TRANSACTION

BEGIN TRANSACTION

SET TRANSACTION ISOLATION LEVEL SERILAIZABLE;

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;

SELECT * FROM employee;

UPDATE employee SET age=5 WHERE age=10;

SELECT * FROM employee;

トランザクション 2 はトランザクション 1 がコミットされるまでブロックされます。

トランザクション 2 はブロッキングなしで進行します。

UPDATE employee SET age=35 WHERE age=30;

COMMIT

トランザクション 1 は正常にコミットされます。

トランザクション 1 は正常にコミットされます。

COMMIT

トランザクション 2 は正常にコミットされます。

トランザクション 2 は正常にコミットされます。

SELECT * FROM employee;

両方のトランザクションからの変更が表示されます。

両方のトランザクションからの変更が表示されます。