OCC 与2PL 的区别举例
下面是会话同时更新同一个表时,两种用户体验的区别:悲观(针对基于磁盘的表)和
乐观(针对MOT 表)。
本例中,使用如下表测试命令:
table “TEST” – create table test (x int, y int, z int, primary key(x));
本示例描述同一测试的两个方面:用户体验(本示例中的操作)和重试要求。
悲观方法示例——用于基于磁盘的表
下面是一个悲观方法例子(非MOT)。任何隔离级别都可能适用。
以下两个会话执行尝试更新单个表的事务。
WAIT LOCK 操作发生,客户端体验是:会话2 卡住,直到会话1 完成COMMIT,会
话2 才能进行。
但是,使用这种方法时,两个会话都成功,并且不会发生异常中止(除非应用了
SERIALIZABLE 或REPEATABLE-READ 隔离级别),这会导致整个事务需要重试。
表13- 5 悲观方法代码示例
时间
会话1
会话2
t0
Begin
Begin
t1
update test set y=200 where x=1;
t2
y=200
Update test set y=300 where x=1; – Wait
on lock
t4
Commit
Unlock
Commit
(in
READ-COMMITTED
this
will
succeed, in SERIALIZABLE it will fail)
y = 300
GBase 8c V5 开发者手册
南大通用数据技术股份有限公司
487
乐观方法示例——用于MOT
下面是一个乐观方法的例子。
它描述了创建一个MOT 表,然后有两个并发会话同时更新同一个MOT 表的情况。
create foreign table test (x int, y int, z int, primary key(x));
OCC 的优点是,在COMMIT 之前没有锁。
OCC 的缺点是,如果另一个会话更新了相同的记录,则更新可能会失败。如果更新失
败(在所有支持的隔离级别中),则必须重试整个会话#2 事务。
更新冲突由内核在提交时通过版本检查机制检测。
会话2 将不会等待其更新操作,并且由于在提交阶段检测到冲突而中止。
表13- 6 乐观方法代码示例——用于MOT
时间
会话1
会话2
t0
Begin
Begin
t1
update test set y=200 where
x=1;
t2
y=200
Update test set y=300 where
x=1;
t4
Commit
y = 300
Commit
ABORT
y = 200