如何在Oracle存储过程中利用DBMS_LOCK实现用户级并发锁?

胖敏小哥_7114

胖敏小哥_7114

2026-10-26

415人浏览

原创

正确使用DBMS_LOCK需先ALLOCATE_UNIQUE获取唯一handle再传给REQUEST,锁名≤100字节且仅含字母数字下划线,x_mode最常用,timeout建议设30而非0,release_on_commit必须显式设FALSE,RELEASE须在正常流程和EXCEPTION中均调用并校验handle非空。

如何在oracle存储过程中利用dbms_lock实现用户级并发锁?

DBMS_LOCK.request() 必须配合 ALLOCATE_UNIQUE 使用

直接传字符串给 DBMS_LOCK.REQUEST 是错的——Oracle 会把它当作锁名,但内部实际用的是锁句柄(handle),而硬编码字符串不经过句柄分配,会导致锁名截断、重复映射或权限异常。正确路径是先调 DBMS_LOCK.ALLOCATE_UNIQUE 拿到唯一 handle,再传给 REQUEST。

常见错误现象:锁名拼成 'MY_PROC_' || p_org_id 后直接传入 REQUEST,结果多个不同 p_org_id 值被截断为相同前缀(如超长时只留前 100 字节),造成误阻塞或漏锁。

  • ALLOCATE_UNIQUE 返回的 lockhandle 是 RAW(128),必须声明为 l_lockhandle VARCHAR2(128) 或 RAW(128),不能用 VARCHAR2(32)
  • 锁名(lockname 参数)长度严格 ≤ 100 字节,含业务上下文如 'INV_ADJ_' || TO_CHAR(p_warehouse_id) || '_' || p_item_code
  • 若 ALLOCATE_UNIQUE 报 ORA-00600,大概率是锁名含空格、点号或斜杠,换成下划线即可

锁模式选 x_mode,timeout 别设 0 除非明确要“抢到就干”

业务级互斥基本只用 x_mode(值为 6),它保证同一时刻只有一个会话能拿到锁。其他模式如 s_mode 或 sx_mode 用于复杂协调场景,日常并发控制反而引入兼容性判断负担。

timeout 设为 0 表示“立即返回”,REQUEST 返回 1(超时)时你得立刻决定跳过或报错;但多数业务需要等待窗口,比如防止报表生成重叠,设 timeout => 30 更稳妥。

QuantOracle
QuantOracle

63个确定性量化金融计算器 + 10个通过MCP的复合工作流。期权定价、Greeks、奇异衍生品、风险指标、投资组合优化……

下载
  • 不要依赖默认 timeout(无限等待),否则一个卡死的会话会让后续所有请求挂住
  • release_on_commit => FALSE 必须显式指定,因为 DBMS_LOCK 锁不随 COMMIT 自动释放
  • 若用自治事务封装锁逻辑,自治事务里 RELEASE 无效——锁属于外层会话,只能在外层释放

释放锁必须覆盖正常流程和 EXCEPTION 两个出口

忘记 DBMS_LOCK.RELEASE 是最危险的疏忽:锁残留后,同名请求永远阻塞,直到数据库重启或 DBA 手动清理 V$LOCK 中的锁记录。这不是事务回滚能解决的问题。

典型翻车点:在主流程末尾写了 RELEASE,但没在 EXCEPTION 块里写,一旦中间抛异常(如除零、NO_DATA_FOUND),锁就卡死了。

  • 释放前检查 handle 是否非空:IF l_lockhandle IS NOT NULL THEN DBMS_LOCK.RELEASE(l_lockhandle); END IF;
  • 不要把 RELEASE 放进自治事务,也不要用 AFTER STATEMENT 触发器——它们无法感知当前会话锁状态
  • 若过程被 RAISE_APPLICATION_ERROR 终止,EXCEPTION 块仍会执行,所以释放逻辑放这里最可靠

锁名必须带业务维度,且不能跨会话复用 handle

锁名不是随便起个名字就行。“my_batch_job” 这种硬编码锁名会让所有调用串行,哪怕参数完全不同;而“job_ || SYSDATE”又导致每次都不重用,失去互斥意义。关键是要让锁名精确反映互斥边界。

例如库存调整存储过程,按仓库 + 物料编码组合锁名:'STOCK_ADJ_' || p_wh_id || '_' || p_item_id。这样同一仓库同一物料的操作互斥,不同仓库可并行。

  • 避免用 SYS_GUID() 或 DBMS_RANDOM.STRING 生成锁名——每次值都不同,锁失效
  • 同一个会话内多次调用同一过程时,不能复用上一次的 lockhandle,必须每次重新 ALLOCATE_UNIQUE
  • 锁名中禁用中文、冒号、斜杠、空格,只用字母、数字、下划线,否则可能触发隐式字符集转换失败
真正难处理的不是加锁,而是锁生命周期管理:它不绑定事务、不自动清理、不参与死锁检测。一个没释放的 x_mode 锁,比一行没提交的 SELECT FOR UPDATE 更隐蔽、更难排查。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
oracle清空表数据
oracle清空表数据

当表中的数据不需要时,则应该删除该数据并释放所占用的空间。本专题为大家提供oracle清空表数据的相关文章,帮助大家解决该问题。

2023.08.16

1021

5

Oracle中declare的使用
Oracle中declare的使用

Oracle DECLARE语句是PL/SQL编程语言中用于声明变量、常量、游标或异常的关键字。它的主要作用是在程序中定义这些对象,以便在后续的代码中使用。DECLARE语句的语法简单明了,可以根据需要声明多个对象。通过使用这些声明的对象,可以进行各种操作,如计算、查询数据库、处理异常等 。

2023.09.15

3013

5

oracle怎么分页
oracle怎么分页

实现分页的步骤:1、使用ROWNUM进行分页查询;2、在执行查询之前进行设置分页参数;3、使用"COUNT(*)"函数来获取总行数,并使用"CEIL"函数来向上取整计算总页数;4、在外部查询中使用"WHERE"子句来筛选出特定的行号范围,以实现分页查询。想了解更多oracle怎么分页的文章,可以来阅读本专题先的文章。

2023.09.18

3030

5

Oracle查看表操作历史记录
Oracle查看表操作历史记录

查看操作历史记录的方法:1、使用Oracle内置的审计功能,可以记录数据库中发生的各种操作,包括登录、DDL语句、DML语句等;2、使用Oracle日志文件,其中包含了数据库中发生的各种操作,可以通过查看日志文件来获取操作历史记录;3、使用Oracle的Flashback功能,可以查看数据库在某个时间点的操作历史记录;4、使用第三方工具等。本专题还提供其他查看表操作的文章,大家可以免费阅读。

2023.09.19

1729

3

Oracle中RAC的用法
Oracle中RAC的用法

Oracle中RAC的用法:1、通过在多个服务器上运行数据库实例来提供高可用性;2、允许在需要时增加或减少节点数量;3、通过将工作负载分布到多个节点上来实现负载均衡;4、使用共享存储来实现多个节点之间的数据共享;5、允许多个节点同时处理数据库请求,从而实现并行处理;6、提供了透明故障切换功能;7、使用了一些技术来确保数据的一致性;8、提供了管理工具来简化RAC环境的管理和维护。本专题还提供RAC相关的其他文章,大家可以免费阅读。

2023.09.19

2353

7

oracle imp
oracle imp

imp是Oracle数据库中的一个命令行工具,用于将导出的数据和对象从一个数据库实例导入到另一个数据库实例。imp命令的一般语法为“imp username/password@connect_string file=file_name [options]”。

2023.09.19

3189

4

常用的数据库软件
常用的数据库软件

常用的数据库软件有MySQL、Oracle、SQL Server、PostgreSQL、MongoDB、Redis、Cassandra、Hadoop、Spark和Amazon DynamoDB。更多关于数据库软件的内容详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.02

4629

19

oracle通配符有哪些
oracle通配符有哪些

oracle通配符有“%”、“_”、“[]”和“[^]"。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.11.08

257

5

oracle四舍五入怎么操作
oracle四舍五入怎么操作

oracle四舍五入操作可以使用ROUND函数来实现,其语法为“ROUND(number, decimal_places)”,其中,number是要进行四舍五入的数值,decimal_places是指定的小数位数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.11.14

826

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程