You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么MySQL中可以多次成功获取同一个GET_LOCK锁?

MySQL GET_LOCK 重复调用返回1的核心原因

1. 锁本身的可重入特性

MySQL的GET_LOCK()属于会话级命名锁,原生支持重入逻辑:同一个数据库连接(会话)已经持有某名称的锁时,重复调用GET_LOCK()获取同名锁会直接返回成功(返回值1),不会触发等待也不会返回失败。只有不同会话尝试获取已被持有的锁时,才会在等待超时后返回0。
同时重入次数会被计数,你调用多少次GET_LOCK()获取同名锁,就需要调用对应次数的RELEASE_LOCK()才能真正释放该锁。如果你的Scala函数多次调用时复用的是同一个数据库连接,就会出现你观察到的重复调用都返回1的情况。

2. 连接池回收连接导致锁提前失效

如果你的服务集成了数据库连接池(如HikariCP、C3P0等),你的函数逻辑可能仅在执行SELECT GET_LOCK('foo',5);时临时从池中借用连接,SQL执行完成后连接就被归还给了连接池。此时MySQL会自动释放该会话持有的所有GET_LOCK锁,你下一次调用函数时拿到的是新的空闲连接,自然可以再次成功获取锁。

注意:GET_LOCK的生命周期完全和数据库会话绑定,事务提交、回滚都不会释放该锁,只有会话断开、主动调用RELEASE_LOCK()、或者同一会话调用GET_LOCK()获取其他名称的锁时,原锁才会被释放。

排查验证方法
  • 调整函数逻辑,在同一个数据库连接会话内连续执行两次SELECT GET_LOCK('foo',5);,如果第二次返回1,即可确认是可重入特性导致的现象
  • 每次执行GET_LOCK后同步执行SELECT CONNECTION_ID();打印当前会话ID,如果两次调用返回的ID不一致,即可确认是连接池回收连接导致锁被提前释放

内容的提问来源于stack exchange,提问作者Greg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 06:27:02