比较 Babelfish 与 SQL Server 隔离级别 - Amazon Aurora

比较 Babelfish 与 SQL Server 隔离级别

以下是一些关于 SQL Server 和 Babelfish 如何实现 ANSI 隔离级别的细微差别的示例。

注意
  • 隔离级别 REPEATABLE READSNAPSHOT 在 Babelfish 中相同。

  • 隔离级别 READ UNCOMMITTEDREAD COMMITTED 在 Babelfish 中相同。

以下示例显示了如何为下面提到的所有示例创建基表:

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 相同。事务 2 中未提交的更改对事务 1 不可见。

空闲事务

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 行都具有 age=99。

id = 4 的行具有年龄值 40,因为在更新查询期间,事务 2 看不到该行。其他行更新为 age=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;

在事务 1 提交之前,事务 2 将被阻止。

事务 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 的行具有 name='A_TX2'。

id=1 的行具有 name='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 更新,此处可见。

id = 3 的行由事务 2 更新。

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);

在事务 1 提交之前,事务 2 将被阻止。

事务 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;

空闲事务

在事务 2 提交之前,事务 1 将被阻止。

事务 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);

空闲事务

在事务 2 提交之前,事务 1 将被阻止。

在事务 2 提交之前,事务 1 将被阻止。

空闲事务

COMMIT

事务 2 成功提交。事务 1 现已解除阻止。

事务 2 成功提交。事务 1 中止,出现错误,原因是重复键值违反了唯一约束。

COMMIT

空闲事务

事务 1 成功提交。

事务 1 提交失败,原因是由于事务之间的读取或写入依赖关系,无法序列化访问。

SELECT * FROM employee;

空闲事务

插入行 (5, 'E', 50)。

仅存在 4 行。

在 Babelfish 中,如果这些事务的执行与这些事务的所有可能的串行(一次一个)执行不一致,则以隔离级别 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;

空闲事务

UPDATE employee SET age=5 WHERE age=10;

空闲事务

空闲事务

SELECT * FROM employee;

在事务 1 提交之前,事务 2 将被阻止。

事务 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;

在事务 1 提交之前,事务 2 将被阻止。

事务 2 在没有任何阻止的情况下继续进行。

空闲事务

UPDATE employee SET age=35 WHERE age=30;

COMMIT

空闲事务

事务 1 成功提交。

事务 1 成功提交。

空闲事务

COMMIT

事务 2 成功提交。

事务 2 成功提交。

SELECT * FROM employee;

空闲事务

这两个事务的更改都是可见的。

这两个事务的更改都是可见的。