比較 Babelfish 和 SQL Server 隔離層級 - Amazon Aurora

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

比較 Babelfish 和 SQL Server 隔離層級

以下是一些範例,示範 SQL Server 和 Babelfish 如何實作 ANSI 隔離層級的細微差異。

注意
  • Babelfish 中的隔離層級 REPEATABLE READSNAPSHOT 是相同的。

  • Babelfish 中的隔離層級 READ UNCOMMITTEDREAD 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 隔離層級

下表提供執行並行交易時,變更讀取的詳細資訊。與 Babelfish 實作相比,其顯示在 SQL Server 中使用 READ UNCOMMITTED 隔離層級時觀察到的結果。

交易 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 相同。交易 1 看不到來自交易 2 的未遞交變更。

交易閒置

COMMIT

SELECT * FROM employee;

交易閒置

查看交易 2 遞交的變更。

查看交易 2 遞交的變更。

Babelfish READ COMMITTED 相較於 SQL Server READ COMMITTED 隔離層級

下表提供執行並行交易時的讀寫封鎖行為詳細資訊。與 Babelfish 實作相比,其顯示在 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;

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 變更尚不可見。更新 id=3 的列。

交易閒置

COMMIT

交易 2 已成功遞交。交易 1 現在已解除封鎖,並查看來自交易 2 的更新。

交易 2 已成功遞交。

SELECT * FROM employee;

交易閒置

交易 1 更新 id = 1 的列。

交易 1 更新 id = 3 的列。

Babelfish READ COMMITTED 相較於 SQL Server READ COMMITTED SNAPSHOT 隔離層級

下表提供的詳細資訊,與執行並行交易時新插入之列的封鎖行為有關。與 READ COMMITTED Babelfish 實作相比,其顯示在 SQL Server 中使用 READ COMMITTED SNAPSHOT 隔離層級時觀察到的結果。

交易 1 交易 2 SQL Server READ COMMITTED SNAPSHOT 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 鎖定。

已更新三列。新插入的列尚不可見。

COMMIT

交易閒置

遞交成功。交易 2 現已解除封鎖。

遞交成功。

交易閒置

SELECT * FROM employee;

所有 4 列都具有存留期=99。

id = 4 之列的存留期值為 40,因為更新查詢期間交易 2 看不到此值。其他列會更新為存留期=99。

Babelfish REPEATABLE READ 相較於 SQL Server REPEATABLE READ 隔離層級

下表提供執行並行交易時的讀寫封鎖行為詳細資訊。與 REPEATABLE READ Babelfish 實作相比,其顯示在 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 的更新。

下表提供執行並行交易時的寫入-寫入封鎖行為詳細資訊。與 REPEATABLE READ Babelfish 實作相比,其顯示在 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;

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 的列名稱為='A_TX2'。

id=1 的列名稱為='A_TX1'。

下表提供執行並行交易時幽靈讀取行為的詳細資訊。與 REPEATABLE READ Babelfish 實作相比,其顯示在 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;

交易閒置

交易閒置

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

交易 2 繼續進行,而沒有任何封鎖。

交易 2 繼續進行,而沒有任何封鎖。

交易閒置

SELECT * FROM employee;

新插入的列是可見的。

新插入的列是可見的。

交易閒置

COMMIT

SELECT * FROM employee;

交易閒置

交易 2 插入的新列是可見的。

交易 2 插入的新列是不可見的。

COMMIT

交易閒置

SELECT * FROM employee;

交易閒置

新插入的列是可見的。

新插入的列是可見的。

下表提供執行並行交易時的詳細資訊,以及與 REPEATABLE READ Babelfish 實作相比,在 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;

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 陳述式會執行,最後更新 id = 3 的列,因為交易 1 變更尚不可見。

交易閒置

SELECT * FROM employee;

此步驟會在交易 1 遞交之後執行。id = 1 的列會由上一步的交易 2 更新,於此處是可見的。

交易 2 會更新 id = 3 的列。

COMMIT

交易閒置

交易 2 現已解除封鎖。

遞交成功。

交易閒置

COMMIT

SELECT * FROM employee;

交易閒置

兩個交易都會在 id = 1 的列上執行更新。

交易 1 和 2 會更新不同的列。

Babelfish SERIALIZABLE 相較於 SQL Server SERIALIZABLE 隔離層級

下表提供執行並行交易時範圍鎖定的詳細資訊。與 SERIALIZABLE Babelfish 實作相比,其顯示在 SQL Server 中使用 SERIALIZABLE 隔離層級時觀察到的結果。

交易 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;

交易閒置

新插入的列是可見的。

新插入的列是可見的。

下表提供執行並行交易時的詳細資訊,以及與 SERIALIZABLE Babelfish 實作相比,在 SQL Server 中使用 SERIALIZABLE 隔離層級時的不同最終結果。

交易 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。

當您 INSERT 進入具有唯一限制條件的資料表時,下表會提供詳細資訊。與 SERIALIZABLE Babelfish 實作相比,其顯示在 SQL Server 中使用 SERIALIZABLE 隔離層級時觀察到的結果。

交易 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 中,以可序列化隔離層級執行的並行交易,若其執行結果與那些交易執行結果所有可能的序列 (一次一個) 不一致,則會因可序列化異常錯誤而失敗。

下表提供執行並行交易時,序列化異常的詳細資訊。與 SERIALIZABLE Babelfish 實作相比,其顯示在 SQL Server 中使用 SERIALIZABLE 隔離層級時觀察到的結果。

交易 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;

交易閒置

兩個交易的變更都是可見的。

兩個交易的變更都是可見的。