Oracle 的 TX、TM、UL 锁对比

Oracle 的 TX、TM、UL 锁对比

Oracle 数据库中的这三种锁机制在并发控制中扮演着不同角色,以下是它们的对比分析:

一、基本特性对比

特性 TX (事务锁) TM (DML锁) UL (用户锁)
锁类型 行级锁 表级锁 应用级自定义锁
作用范围 保护数据行变更 保护表结构不被修改 保护用户定义的资源
自动性 事务自动获取/释放 DML语句自动获取/释放 需显式调用DBMS_LOCK获取
可见性 其他会话可见 其他会话可见 仅申请会话可见(默认)
冲突检测 通过等待或死锁检测 立即冲突报错(ORA-00054) 可配置等待或立即失败

二、技术实现对比

1. 数据结构差异

  • TX锁

    sql 复制代码
    -- 在v$lock中的表示
    TYPE='TX', ID1=USN.SLOT, ID2=WRAP#
    -- USN=undo段号,SLOT=槽位号,WRAP=序列号
  • TM锁

    sql 复制代码
    TYPE='TM', ID1=OBJECT_ID, ID2=0
    -- 直接关联数据字典对象ID
  • UL锁

    sql 复制代码
    TYPE='UL', ID1=<lock_id>, ID2=0
    -- lock_id由DBMS_LOCK.ALLOCATE_UNIQUE生成

2. 锁模式对比

模式 TX锁表现 TM锁表现 UL锁表现
共享(SS) SELECT...FOR UPDATE LOCK TABLE IN SHARE MODE DBMS_LOCK.REQUEST(mode=>'S')
排他(X) UPDATE/DELETE操作 LOCK TABLE IN EXCLUSIVE MODE DBMS_LOCK.REQUEST(mode=>'X')
空(N) 事务结束释放 语句结束释放 DBMS_LOCK.RELEASE调用

三、使用场景对比

1. TX锁典型场景

sql 复制代码
-- 案例1:行级更新冲突
UPDATE employees SET salary=salary*1.1 WHERE emp_id=100;
-- 此时会在emp_id=100的记录上获得TX锁

-- 案例2:死锁场景
-- 会话1: UPDATE tableA SET... WHERE id=1;
-- 会话2: UPDATE tableB SET... WHERE id=2;
-- 会话1: UPDATE tableB SET... WHERE id=2; -- 等待
-- 会话2: UPDATE tableA SET... WHERE id=1; -- 死锁检测

2. TM锁典型场景

sql 复制代码
-- 案例1:防止DDL与DML冲突
-- 会话1: SELECT * FROM orders FOR UPDATE;
-- 会话2: ALTER TABLE orders ADD column new_col NUMBER; -- 等待TM锁

-- 案例2:LOCK TABLE显式锁定
LOCK TABLE inventory IN EXCLUSIVE MODE;

3. UL锁典型场景

sql 复制代码
-- 案例1:应用级资源协调
DECLARE
  l_lockhandle VARCHAR2(128);
  l_status NUMBER;
BEGIN
  DBMS_LOCK.ALLOCATE_UNIQUE('APP_CONFIG_LOCK', l_lockhandle);
  l_status := DBMS_LOCK.REQUEST(l_lockhandle, DBMS_LOCK.X_MODE);
  IF l_status = 0 THEN
    -- 执行需要互斥的操作
    DBMS_LOCK.RELEASE(l_lockhandle);
  END IF;
END;

四、诊断与问题处理

1. 锁等待分析

sql 复制代码
-- 查看所有锁等待
SELECT 
  l1.sid holding_sid,
  l2.sid waiting_sid,
  l1.type lock_type,
  CASE l1.type
    WHEN 'TX' THEN '行锁/事务锁'
    WHEN 'TM' THEN '表锁'
    WHEN 'UL' THEN '用户锁'
  END lock_desc,
  s1.username holder,
  s2.username waiter
FROM v$lock l1, v$lock l2, v$session s1, v$session s2
WHERE l1.block = 1 
AND l2.request > 0
AND l1.id1 = l2.id1
AND l1.id2 = l2.id2
AND l1.sid = s1.sid
AND l2.sid = s2.sid;

2. 特殊问题处理

  • TX锁堆积

    sql 复制代码
    -- 查找长事务
    SELECT s.sid, s.serial#, s.username, s.status,
           t.start_time, t.used_ublk
    FROM v$transaction t, v$session s
    WHERE t.ses_addr = s.saddr
    ORDER BY t.used_ublk DESC;
  • TM锁冲突

    sql 复制代码
    -- 查找被锁定的对象
    SELECT object_name, object_type 
    FROM dba_objects 
    WHERE object_id = (SELECT id1 FROM v$lock WHERE type='TM' AND sid=&sid);
  • UL锁泄漏

    sql 复制代码
    -- 检查未释放的用户锁
    SELECT * FROM dba_lock_internal 
    WHERE lock_type = 'UL' 
    AND owner <> 'SYS';

五、性能优化建议

  1. TX锁优化

    • 减少事务持续时间
    • 使用SELECT...FOR UPDATE NOWAIT避免等待
    • 适当增加_TRANSACTION_TABLE_SIZE参数
  2. TM锁优化

    • 避免业务高峰期执行DDL
    • 对大表DDL使用ONLINE选项
    • 考虑使用LOCK TABLE IN SHARE MODE替代排他模式
  3. UL锁最佳实践

    • 为锁命名使用前缀(如APPNAME_RESOURCE)
    • 设置超时参数:DBMS_LOCK.REQUEST(..., timeout=>10)
    • 在异常处理中确保锁释放

六、版本差异说明

版本 TX锁增强 TM锁变化 UL锁改进
11g 增加TX绑定特性 引入ONLINE DDL 增加锁超时精确控制
12c 支持IN_MEMORY事务 支持DDL等待超时 增加锁状态持久化选项
19c 自适应死锁检测算法 减少索引维护的TM锁 支持PL/SQL锁监控视图
21c 自动锁转换优化 分区表DDL锁粒度细化 增加全局UL锁命名空间

理解这三种锁的差异,可以帮助DBA更好地诊断并发问题并优化数据库性能。

相关推荐
扫描电镜3 分钟前
从 G1 到 G7:台式扫描电镜在稳定性与自动化上的技术演进
运维·人工智能·自动化
wanhengidc4 分钟前
电脑端 云手机都有哪些注意事项
运维·服务器·安全·智能手机·云计算
码农阿豪9 分钟前
兼容是基石,超越是未来:金仓数据库的三重革新
数据库
2022.11.7始学前端10 分钟前
n8n第十三节 三个节点测试技巧
运维·服务器·n8n
廋到被风吹走13 分钟前
【数据库】【Redis】基本概念和特点
数据库·redis·缓存
榮十一14 分钟前
10道SQL练习题及答案
数据库·sql·算法
RedMery20 分钟前
Ubuntu切换wayland和x11
linux·运维·ubuntu
Hns.21 分钟前
MySQL慢SQL问题查找与优化方案
数据库·sql·mysql
专业开发者22 分钟前
思科以终端产品解决方案提供商的身份实现效能提升
运维·服务器·网络
一水鉴天22 分钟前
整体设计 定稿 之6 完整设计文档讨论及定稿 之3 整体设计原则(原型-过程-模块三阶联动体系)
前端·数据库·人工智能