调用程序Locking issue问题:pgmA更新detail file如何规避锁冲突
避免自锁冲突的Detail File更新方案
下面是适配老系统低侵入性的可行方案,均不需要全量分析改造上层50个调用程序:
1. 异步队列延迟更新(首推方案)
这是完全无锁冲突的方案,改造量极小:
- 在pgmA中不执行实时更新操作,将解析XML得到的待更新记录主键、字段值、请求时间写入中转队列表
DETAIL_UPDATE_QUEUE,标记为待处理状态 - 单独部署一个独立的后台定时作业,周期扫描队列中待处理的记录,此时上层调用程序的事务已提交、记录锁已全部释放,后台作业直接执行更新即可
- 队列增加幂等校验逻辑,避免重复更新同一条记录
该方案全程不会和上层调用程序抢锁,仅需修改pgmA逻辑+新增一个轻量批处理作业,无需改动任何上层老旧程序
2. 乐观锁无冲突更新
如果可以接受对Detail File做极小的表结构改动,可以采用乐观锁机制:
- 给Detail File新增
VERSION整数字段或者LAST_UPDATE_TIME时间戳字段,原有记录默认赋值为0/创建时间 - pgmA执行更新时执行语句:
UPDATE DETAIL_FILE SET [待更新字段列表], VERSION = VERSION + 1 WHERE [主键条件] AND VERSION = [查询到的当前版本号] - 如果语句返回影响行数为0,说明记录已被上层程序修改或锁定,直接将该更新请求转入上述异步队列后续处理即可
该方案无需额外常驻后台作业,大部分无冲突的更新可以实时完成,只有冲突场景走异步流程
3. 锁状态预检测更新
如果无法修改Detail File表结构,可以调用系统原生API做锁预检测:
- pgmA执行更新前,调用操作系统/数据库提供的锁检测接口,校验待更新的记录是否已被当前作业持有锁:
- IBM i平台可调用
QWCJRCTAPI查询当前作业的记录锁持有情况,或执行ALCOBJ带测试参数判断锁是否可用 - 通用数据库可执行
SELECT ... FOR UPDATE NOWAIT语句,捕获锁等待异常即可判断记录已被锁定
- IBM i平台可调用
- 检测无锁则执行实时更新,检测到锁存在则转入异步队列处理
该方案不需要修改表结构,也不需要全量梳理上层调用逻辑
方案选型建议
- 老系统改造优先选异步队列方案,改造成本最低、稳定性最高,完全避免锁冲突风险
- 实时性要求较高的场景可以选择乐观锁+冲突异步降级的组合方案
- 既不能改表也不想加后台作业的场景,选择锁预检测方案即可
内容的提问来源于stack exchange,提问作者Sam K
相关产品推荐
相关产品推荐

