ALTER TABLE STAFF ADD COLUMN TS TIMESTAMP NOT NULL
GENERATED ALWAYS FOR EACH ROW ON UPDATE AS
ROW CHANGE TIMESTAMP
通过查询得到结果集的行标识符、时间标识符 , 然后执行 COMMIT 操作。
SELECT RID_BIT(STAFF),ROW CHANGE TOKEN FOR STAFF,ID,NAME,DEPT,JOB,TS
FROM STAFF WHERE ID=70
COMMIT
乐观锁定表达式
STAFF 表
RID_BIT
ROW CHANGE TOKEN
ID
NAME
DEPT
JOB
ROW CHANGE TIMESTAMP
x'0A000006000000000000000000FCF84F'
74904229642240
70
Rothman
15
Sales
0001-01-01-00.00.00.000000
使用 DBA1 之前查询出来的行标识符、时间标识符来更新行。
UPDATE STAFF SET JOB = 'Mgr'
WHERE RID_BIT(STAFF)=x'0A000006000000000000000000FCF84F'
AND ROW CHANGE TOKEN FOR STAFF=74904229642240
ALTER TABLE STAFF ADD COLUMN TS TIMESTAMP NOT NULL GENERATED
ALWAYS FOR EACH ROW ON UPDATE AS ROW CHANGE TIMESTAMP
乐观锁定表达式
STAFF 表
RID_BIT
ROW CHANGE TOKEN
ID
NAME
DEPT
JOB
ROW CHANGE TIMESTAMP
x'0A00400B00000000000000000465A5C1'
141401934713623382
70
Rothman
15
Mgr
2009-07-02-15.30.18.562006
UPDATE STAFF SET JOB = 'Engineer' WHERE ID=70
OR
UPDATE STAFF SET JOB = 'Engineer'
WHERE RID_BIT(STAFF)= x'0A00400B00000000000000000465A5C1'
AND ROW CHANGE TOKEN FOR STAFF=141401934713623382
乐观锁定表达式
STAFF 表
RID_BIT
ROW CHANGE TOKEN
ID
NAME
DEPT
JOB
ROW CHANGE TIMESTAMP
x'0A00400B00000000000000000465A5C1'
141401934875088080
70
Rothman
15
Engineer
2009-07-02-15.32.44.546000
使用 DBA1 之前查询得到的行标识符、时间标识符来更新行。
UPDATE STAFF SET JOB = 'Engi'
WHERE RID_BIT(STAFF)= x'0A00400B00000000000000000465A5C1'
AND ROW CHANGE TOKEN FOR STAFF=141401934713623382
UPDATE STAFF SET JOB = 'GM' WHERE ID=70
OR
UPDATE STAFF SET JOB = 'GM'
WHERE RID_BIT(STAFF)= x'0A00000600000000000000000465ABC4'
AND ROW CHANGE TOKEN FOR STAFF=141401936241179608
通过之前查询得到的 ROW CHANGE TOKEN/RID_BIT() 定位。
UPDATE STAFF SET JOB = 'Clerk'
WHERE RID_BIT(STAFF)= x'0A00400B00000000000000000465EFF9'
AND ROW CHANGE TOKEN FOR STAFF=7632868011317133312
通过查询得到结果集的行标识符、时间标识符 , 然后执行 COMMIT 操作。
SELECT RID_BIT(STAFF),ROW CHANGE TOKEN FOR STAFF,ID,NAME,DEPT,JOB,TS
FROM STAFF WHERE ID=120
COMMIT
乐观锁定表达式
STAFF 表
RID_BIT
ROW CHANGE TOKEN
ID
NAME
DEPT
JOB
ROW CHANGE TIMESTAMP
x'0F0000060000000000000000055F4927'
141402635178433027
120
Naughton
38
Clerk
2009-07-07-18.36.01.875011
表 20. 同一数据页面上还存在的其他一些记录 下面几条记录都属于同一数据页面。
乐观锁定表达式
STAFF 表
RID_BIT
ROW CHANGE TOKEN
ID
NAME
DEPT
JOB
x'0B0000060000000000000000055F4927'
141402635178433023
80
James
20
Clerk
x'0C0000060000000000000000055F4927'
141402635178433024
90
Koonitz
42
Sales
x'0D0000060000000000000000055F4927'
141402635178433025
100
Plotz
42
Mgr
x'0E0000060000000000000000055F4927'
141402635178433026
110
Ngan
15
Clerk
更新同一数据页面上的另外一条记录。
UPDATE STAFF SET JOB = 'VP'
WHERE RID_BIT(STAFF)= x'0D0000060000000000000000055F4927'
AND ROW CHANGE TOKEN FOR STAFF=141402635178433025
乐观锁定表达式
STAFF 表
RID_BIT
ROW CHANGE TOKEN
ID
NAME
DEPT
JOB
ROW CHANGE TIMESTAMP
x'0D0000060000000000000000055F4927'
141402635937539040
100
Plotz
42
VP
2009-07-07-18.47.21.812000
通过之前查询得到的 ROW CHANGE TOKEN/RID_BIT() 定位,更新成功。
UPDATE STAFF SET JOB = 'Mgr'
WHERE RID_BIT(STAFF)= x'0F0000060000000000000000055F4927'
AND ROW CHANGE TOKEN FOR STAFF=141402635178433027
根据之前查询得到的行标识符、行更改标记执行更新操作,很明显,更新操作不能成功。
即使行标识符可能仍然指向有效的记录(已经不是原来的那条记录,因为这个位置可能已经被新的记录所占据),
但是行更改标记也已经发生了改变,所以使用之前查询得到的行标识符、行更改标记进行匹配,
匹配不到记录,所以更新操作不能成功。
UPDATE STAFF SET JOB = 'Mgr'
WHERE RID_BIT(STAFF)= x'1200400B00000000000000000465EFF9'
AND ROW CHANGE TOKEN FOR STAFF=74904229642240
结束语
为了避免在使用悲观锁定技术时可能引发的锁等待而导致的并发性问题,乐观锁定技术最小化了给定资源对于其他事务的不可用时间。通过使用乐观锁定,数据库管理器在完成读操作之后可以立即释放锁。
DB2 V9.5 支持更高效的乐观锁定,而且避免了误判的发生。这些支持通过行标识符(RID_BIT 或 RID)内置函数、行更改标识符 (ROW CHANGE TOKEN 表达式 ) 实现的。使用这种编程模型的应用程序可以从增强的乐观锁定特性受益,并且能够进一步增强并发性。
<!-- CMA ID: 419144 --><!-- Site ID: 10 --><!-- XSLT stylesheet used to transform this file: dw-document-html-6.0.xsl -->
原文地址:http://www.ibm.com/developerworks/cn/data/library/techarticles/dm-0908renzg/