《A Critique of ANSI SQL Isolation Levels》论文实验

《A Critique of ANSI SQL Isolation Levels》论文实验

1序言

《A Critique of ANSI SQL Isolation Levels》是理解数据库隔离性的最关键论文之一。

论文对异常现象给出了明确的定义。依据异常现象,可以确定的划分与比较数据库产品的隔离级别。

主要异常现象包括:

  • 读未提交(A1)
  • 不可重复读(A2)
  • 幻象(A3)
  • 更新丢失(P4)
  • 幻象(A3B)
  • Write Skew(A5B)
  • Read Skew(A5A)

本文对Oracle、PostgreSQL、MySQL(InnoDB)的各个隔离级别下的异常操作进行了实验,结果可用判断数据库隔离级别的差异。对于新的数据库与中间件产品,可以采用此方法判断其隔离级别的实际水平。


2 结果汇总与分析

Oracle Read Committed、PG Read Committed与 InnoDB Read Committed能力一致。

Oracle Serializable、PG Repeatable Read能力一致。InnoDB Repeatable Read比前两者低。

PG Serializable与InnoDB Serializable能力一致。


3 Oracle

3.1 Oracle read committed

脏读A1(不出现)

操作序列:

P1: w1[x]...r2[x]...(c1 or a1) and (c2 or a2) in any order

A1: w1[x]...r2[x]...(a1 and c2 in any order)

异常是否出现:否

操作步骤:

不可重复读A2(出现)

操作序列:

P2: r1[x]..w2[x]..(c1 or a1) and (c2 or a2) in any order

A2: r1[x]..w2[x]..c2..r1[x]..c1

异常是否出现:是

操作步骤:

幻象A3(出现)

操作序列:

P3:r1[P]..wi[2][y in P]..(c1 or a1) and (c2 or a2) in any order

A3:r1[P]..wi[2][y in P]..c2..r1[P]..c1

异常是否出现:是

操作步骤:

更新丢失P4(出现)

操作序列:

P4: r1[x]...w2[x]...w1[x]...c1 (Lost Update)

是否出现异常:是

操作序列:

Read skewA5A(出现)

操作序列:

A5A: r1[x]..w2[x]..w2[ y]..c2..r1[y]...(c1 or a1)

是否出现异常:是

操作序列:

write skewA5B(出现)

操作序列:

A5B: r1[x]...r2[y]..w1[y]..w2[x]..(c1 and c2 occur)

是否出现异常:是

操作序列:

幻象A3B(出现)

操作序列:

b1..b2..r1[P]..w1[y in P]..r2[P]..w2[y in P]..c1..c2

是否出现异常:是

操作序列:

3.2 Oracle serializable

脏读A1(不出现)

操作序列:

P1: w1[x]...r2[x]...(c1 or a1) and (c2 or a2) in any order

A1: w1[x]...r2[x]...(a1 and c2 in any order)

异常是否出现:否

操作步骤:

不可重复读A2(不出现)

操作序列:

P2: r1[x]..w2[x]..(c1 or a1) and (c2 or a2) in any order

A2: r1[x]..w2[x]..c2..r1[x]..c1

异常是否出现:否

操作步骤:

幻象A3(不出现)

操作序列:

P3:r1[P]..wi[2][y in P]..(c1 or a1) and (c2 or a2) in any order

A3:r1[P]..wi[2][y in P]..c2..r1[P]..c1

异常是否出现:否

操作步骤:

更新丢失P4(不出现)

操作序列:

P4: r1[x]...w2[x]...w1[x]...c1 (Lost Update)

是否出现异常:不出现

操作序列:

Read skewA5A(不出现)

操作序列:

A5A: r1[x]..w2[x]..w2[ y]..c2..r1[y]...(c1 or a1)

是否出现异常:否

操作序列:

write skewA5B(出现)

操作序列:

A5B: r1[x]...r2[y]..w1[y]..w2[x]..(c1 and c2 occur)

是否出现异常:是

操作序列:

幻象A3B(出现)

操作序列:

b1..b2..r1[P]..w1[y in P]..r2[P]..w2[y in P]..c1..c2

是否出现异常:是

操作序列:


4 PostgreSQL

4.1 pg read committed

以下会话设置隔离级别

SET SESSION CHARACTERISTICS AS TRANSACTION isolation level read committed;

脏读A1(不出现)

操作序列:

P1: w1[x]...r2[x]...(c1 or a1) and (c2 or a2) in any order

A1: w1[x]...r2[x]...(a1 and c2 in any order)

异常是否出现:否

操作步骤:

不可重复读A2(出现)

操作序列:

P2: r1[x]..w2[x]..(c1 or a1) and (c2 or a2) in any order

A2: r1[x]..w2[x]..c2..r1[x]..c1

异常是否出现:是

操作步骤:

幻象A3(出现)

操作序列:

P3:r1[P]..wi[2][y in P]..(c1 or a1) and (c2 or a2) in any order

A3:r1[P]..wi[2][y in P]..c2..r1[P]..c1

异常是否出现:是

操作步骤:

更新丢失P4(出现)

操作序列:

P4: r1[x]...w2[x]...w1[x]...c1 (Lost Update)

是否出现异常:是

操作序列:

Read skewA5A(出现)

操作序列:

A5A: r1[x]..w2[x]..w2[ y]..c2..r1[y]...(c1 or a1)

是否出现异常:是

操作序列:

write skewA5B(出现)

操作序列:

A5B: r1[x]...r2[y]..w1[y]..w2[x]..(c1 and c2 occur)

是否出现异常:是

操作序列:

幻象A3B(出现)

操作序列:

b1..b2..r1[P]..w1[y in P]..r2[P]..w2[y in P]..c1..c2

是否出现异常:是

操作序列:

4.2 pg repeatable read

会话设置如下隔离级别

SET SESSION CHARACTERISTICS AS TRANSACTION isolation level repeatable read;

脏读A1(不出现)

操作序列:

P1: w1[x]...r2[x]...(c1 or a1) and (c2 or a2) in any order

A1: w1[x]...r2[x]...(a1 and c2 in any order)

异常是否出现:否

操作步骤:

不可重复读A2(不出现)

操作序列:

P2: r1[x]..w2[x]..(c1 or a1) and (c2 or a2) in any order

A2: r1[x]..w2[x]..c2..r1[x]..c1

异常是否出现:否

操作步骤:

幻象A3(不出现)

操作序列:

P3:r1[P]..wi[2][y in P]..(c1 or a1) and (c2 or a2) in any order

A3:r1[P]..wi[2][y in P]..c2..r1[P]..c1

异常是否出现:否

操作步骤:

更新丢失P4(不出现)

操作序列:

P4: r1[x]...w2[x]...w1[x]...c1 (Lost Update)

是否出现异常:否

操作序列:

Read skewA5A(不出现)

操作序列:

A5A: r1[x]..w2[x]..w2[ y]..c2..r1[y]...(c1 or a1)

是否出现异常:否

操作序列:

write skewA5B(出现)

操作序列:

A5B: r1[x]...r2[y]..w1[y]..w2[x]..(c1 and c2 occur)

是否出现异常:是

操作序列:

幻象A3B(出现)

操作序列:

b1..b2..r1[P]..w1[y in P]..r2[P]..w2[y in P]..c1..c2

是否出现异常:是

操作序列:

4.3 pg serializable

设置会话级别

SET SESSION CHARACTERISTICS AS TRANSACTION isolation level serializable;

脏读A1(不出现)

操作序列:

P1: w1[x]...r2[x]...(c1 or a1) and (c2 or a2) in any order

A1: w1[x]...r2[x]...(a1 and c2 in any order)

异常是否出现:否

操作步骤:

不可重复读A2(不出现)

操作序列:

P2: r1[x]..w2[x]..(c1 or a1) and (c2 or a2) in any order

A2: r1[x]..w2[x]..c2..r1[x]..c1

异常是否出现:否

操作步骤:

幻象A3(不出现)

操作序列:

P3:r1[P]..wi[2][y in P]..(c1 or a1) and (c2 or a2) in any order

A3:r1[P]..wi[2][y in P]..c2..r1[P]..c1

异常是否出现:否

操作步骤:

更新丢失P4(不出现)

操作序列:

P4: r1[x]...w2[x]...w1[x]...c1 (Lost Update)

是否出现异常:否

操作序列:


Read skewA5A(不出现)

操作序列:

A5A: r1[x]..w2[x]..w2[ y]..c2..r1[y]...(c1 or a1)

是否出现异常:否

操作序列:

write skewA5B(不出现)

操作序列:

A5B: r1[x]...r2[y]..w1[y]..w2[x]..(c1 and c2 occur)

是否出现异常:否

操作序列:

幻象A3B(不出现)

操作序列:

b1..b2..r1[P]..w1[y in P]..r2[P]..w2[y in P]..c1..c2

是否出现异常:是

操作序列:


5 InnoDB

5.1 InnoDB read committed

设置隔离级别

set session transaction isolation level Read committed;

脏读A1(不出现)

操作序列:

P1: w1[x]...r2[x]...(c1 or a1) and (c2 or a2) in any order

A1: w1[x]...r2[x]...(a1 and c2 in any order)

异常是否出现:否

操作步骤:

不可重复读A2(出现)

操作序列:

P2: r1[x]..w2[x]..(c1 or a1) and (c2 or a2) in any order

A2: r1[x]..w2[x]..c2..r1[x]..c1

异常是否出现:是

操作步骤:

幻象A3(出现)

操作序列:

P3:r1[P]..wi[2][y in P]..(c1 or a1) and (c2 or a2) in any order

A3:r1[P]..wi[2][y in P]..c2..r1[P]..c1

异常是否出现:是

操作步骤:

更新丢失P4(出现)

操作序列:

P4: r1[x]...w2[x]...w1[x]...c1 (Lost Update)

是否出现异常:是

操作序列:

Read skewA5A(出现)

操作序列:

A5A: r1[x]..w2[x]..w2[ y]..c2..r1[y]...(c1 or a1)

是否出现异常:是

操作序列:

write skewA5B(出现)

操作序列:

A5B: r1[x]...r2[y]..w1[y]..w2[x]..(c1 and c2 occur)

是否出现异常:是

操作序列:

幻象A3B(出现)

操作序列:

b1..b2..r1[P]..w1[y in P]..r2[P]..w2[y in P]..c1..c2

是否出现异常:是

操作序列:


5.2 InnoDB repeatable read

设置会话隔离级别语句

set session transaction isolation level Repeatable read;

脏读A1(不出现)

操作序列:

P1: w1[x]...r2[x]...(c1 or a1) and (c2 or a2) in any order

A1: w1[x]...r2[x]...(a1 and c2 in any order)

异常是否出现:否

操作步骤:

不可重复读A2(不出现)

操作序列:

P2: r1[x]..w2[x]..(c1 or a1) and (c2 or a2) in any order

A2: r1[x]..w2[x]..c2..r1[x]..c1

异常是否出现:否

操作步骤:

幻象A3(不出现)

操作序列:

P3:r1[P]..wi[2][y in P]..(c1 or a1) and (c2 or a2) in any order

A3:r1[P]..wi[2][y in P]..c2..r1[P]..c1

异常是否出现:否

操作步骤:

更新丢失P4(出现)

操作序列:

P4: r1[x]...w2[x]...w1[x]...c1 (Lost Update)

是否出现异常:是

操作序列:

Read skewA5A(不出现)

操作序列:

A5A: r1[x]..w2[x]..w2[ y]..c2..r1[y]...(c1 or a1)

是否出现异常:否

操作序列:

write skewA5B(出现)

操作序列:

A5B: r1[x]...r2[y]..w1[y]..w2[x]..(c1 and c2 occur)

是否出现异常:是

操作序列:

幻象A3B(出现)

操作序列:

b1..b2..r1[P]..w1[y in P]..r2[P]..w2[y in P]..c1..c2

是否出现异常:是

操作序列:

InnoDB serializable

设置隔离级别

set session transaction isolation level serializable;

脏读A1(不出现)

操作序列:

P1: w1[x]...r2[x]...(c1 or a1) and (c2 or a2) in any order

A1: w1[x]...r2[x]...(a1 and c2 in any order)

异常是否出现:否

操作步骤:

不可重复读A2(不出现)

操作序列:

P2: r1[x]..w2[x]..(c1 or a1) and (c2 or a2) in any order

A2: r1[x]..w2[x]..c2..r1[x]..c1

异常是否出现:否

操作步骤:

幻象A3(不出现)

操作序列:

P3:r1[P]..wi[2][y in P]..(c1 or a1) and (c2 or a2) in any order

A3:r1[P]..wi[2][y in P]..c2..r1[P]..c1

异常是否出现:否

操作步骤:

更新丢失P4(不出现)

操作序列:

P4: r1[x]...w2[x]...w1[x]...c1 (Lost Update)

是否出现异常:否

操作序列:

Read skewA5A(不出现)

操作序列:

A5A: r1[x]..w2[x]..w2[ y]..c2..r1[y]...(c1 or a1)

是否出现异常:否

操作序列:

write skewA5B(不出现)

操作序列:

A5B: r1[x]...r2[y]..w1[y]..w2[x]..(c1 and c2 occur)

是否出现异常:否

操作序列:

幻象A3B(不出现)

操作序列:

b1..b2..r1[P]..w1[y in P]..r2[P]..w2[y in P]..c1..c2

是否出现异常:是

操作序列:



版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)

编辑于 2018-06-21

文章被以下专栏收录