温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

锁等待问题怎么解决

发布时间:2026-10-14 01:31:46 来源:亿速云 阅读:110 作者:小樊 栏目:数据库

“锁等待(Lock Wait / 锁阻塞)”是数据库和多线程开发中非常常见的问题。要解决它,需要先定位原因,再针对性处理。下面我按「通用思路 → 数据库场景 → 代码/并发场景 → 预防建议」来说明。


一、通用解决思路(先做什么)

  1. 确认是否真的在等锁

    • 数据库:看 lock wait timeout、blocking session
    • 代码:看线程是否卡在 synchronized / Lock.lock()
  2. 找到“持锁者”

    • 是谁持有锁不释放?
    • 持锁时间是否正常?
  3. 判断锁类型

    • 行锁 / 表锁
    • 读锁 / 写锁
    • 死锁 or 长时间阻塞

二、数据库中的锁等待(最常见)

1️⃣ MySQL 锁等待

常见原因

  • 事务未提交(BEGIN 后忘了 COMMIT)
  • 大事务
  • 更新条件不走索引(行锁变表锁)
  • 高并发写同一行

排查方法

-- 查看当前锁等待
SELECT * FROM information_schema.innodb_lock_waits;

-- 查看事务
SELECT * FROM information_schema.innodb_trx;

-- 查看进程
SHOW PROCESSLIST;

解决方法

  • 杀掉阻塞事务:
KILL <trx_mysql_thread_id>;
  • 缩短事务:
    • 不在事务里做 RPC / HTTP
  • 加索引,避免锁升级
  • 调整超时时间(临时):
SET innodb_lock_wait_timeout = 30;

2️⃣ Oracle 锁等待

SELECT * FROM v$lock;
SELECT * FROM v$session WHERE blocking_session IS NOT NULL;

解决

  • 找 blocking_session
  • ALTER SYSTEM KILL SESSION 'sid,serial#';

3️⃣ PostgreSQL

SELECT * FROM pg_locks;
SELECT * FROM pg_stat_activity WHERE wait_event_type = 'Lock';

三、Java / 多线程中的锁等待

1️⃣ synchronized 等待

原因

  • 锁粒度太大
  • 持锁线程执行慢

解决

  • 减小锁范围
  • 使用 Lock + tryLock
if (lock.tryLock(1, TimeUnit.SECONDS)) {
    try {
        // do work
    } finally {
        lock.unlock();
    }
}

2️⃣ 死锁(特殊锁等待)

特征

  • 互相等待
  • 永不释放

排查

jstack <pid>

看 deadlock 关键字

解决

  • 固定加锁顺序
  • 使用超时机制

四、常见“坑”总结(非常重要)

❌ 在事务里:

  • sleep
  • 调用第三方接口
  • 人工审核

✅ 正确做法:

  • 事务越短越好
  • 只在数据库层加锁
  • 写操作条件必须走索引

五、如何预防锁等待

  • 控制事务大小
  • 避免热点行更新
  • 使用乐观锁(version 字段)
  • 读写分离
  • 监控锁等待告警

如果你能告诉我:

  • 用的是 哪种数据库 / 语言
  • 报错信息或现象(如 Lock wait timeout exceeded)

我可以给你更精准的解决方案。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI
助
手