使用 DB2 V9.1 for z/OS 实现应用程序会话锁定
2007-08-14 16:23:02 来源:WEB开发网启动一个对锁请求进行处理的子线程。
等待子线程发出表示锁请求处理完成的信号,这时结果已经可用了。
在子线程中,打开新的 DB2 连接,在锁表中获取具有所请求的资源 ID 的一行。在这里,使用 SKIP LOCKED DATA 特性只获得未被 DB2 锁定的行(例如,如果另一个应用程序持有这个资源上的会话锁,就不能获得这一行)。DB2 并不在获取操作中等待。见 清单 2 中的示例代码。现在,请求的结果必须在主线程中可用。子线程等待主线程的终止信号。如果授予了会话锁,它就持有锁表中一行上的 DB2 更新锁,直到发生以下情况为止:
调用 unlock() 或者
应用程序终止。
lock() 函数主线程从子线程获得结果。如果授予了锁,那么 lock() 函数返回调用者。否则子线程被终止。
清单 2. 在子线程中实现 lock() 的 SQL 代码
DECLARE C1 CURSOR FOR
SELECT ResourceId FROM LockTable WHERE ResourceId=:resourceId
FOR UPDATE WITH CS SKIP LOCKED DATA;
OPEN C1;
FETCH C1;
if (sqlca.sqlcode==NO_DATA_FOUND) {
result=indexAlreadyLocked;
} else {
result=lockGranted;
}
实现 unlock() 函数
提供一个 unlock() 函数,它将终止仍然持有锁表中某一行的 DB2 更新锁的子线程。子线程中的终止代码关闭 SQL 游标,并使事务回滚,见 清单 3。因此,会释放这一行的 DB2 更新锁,清单 2 中的下一个 SQL select 语句会看到这一行。
清单 3. 在子线程中实现 unlock() 的 SQL 代码 CLOSE C1;
ROLLBACK WORK;
控制同时访问一个资源的应用程序数量
对以上方式做一项简单的修改,就可以控制同时访问一个资源集的应用程序数量:
如果锁表中有重复的行,就可以对资源进行并发使用。锁表中一个资源的行数决定了可以同时访问这个资源的最大应用程序数量。
清单 4. 填充锁表来控制同时访问的最大应用程序数量的 SQL 示例 INSERT INTO LockTable VALUES('INDEX 1');
INSERT INTO LockTable VALUES('INDEX 1');
INSERT INTO LockTable VALUES('INDEX 2');
INSERT INTO LockTable VALUES('INDEX 2');
INSERT INTO LockTable VALUES('INDEX 2');
按照这段代码,最多有两个应用程序可以同时访问 ‘INDEX 1’,最多有三个应用程序可以同时访问 ‘INDEX 2’。
结束语
有一种简单可靠的解决方案模式可用于在应用程序级别实现会话锁。它依赖于 DB2 Version 9.1 for z/OS 中的新特性 SKIP LOCKED DATA,且已成功应用于一个 DB2 开发项目。
更多精彩
赞助商链接