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

数据库死锁引发饥饿问题求助:事务时间戳机制实现咨询

啊,这个死锁引发的饥饿问题确实挺闹心的——每次重试都被新冒出来的事务挤掉,根本没机会跑完对吧?时间戳机制之所以能搞定这个,核心是给每个事务分配一个全局唯一的时间戳,用这个时间戳来明确事务的“优先级”,从根源上避免老事务一直被当成牺牲者。下面我给你拆解两种工业界最常用的实现方案:

Wait-Die 算法

这是一种“谦让式”的冲突处理逻辑,核心是老事务优先等待,新事务主动终止:

  • 每个事务启动时,系统会给它分配一个递增的时间戳(可以用系统时钟,也可以用全局计数器,总之越早启动的事务,时间戳数值越小)
  • 当事务T请求被事务S持有的锁时:
    • 如果T的时间戳 < S的时间戳(T是更早启动的老事务):T乖乖等待,直到S释放锁或者S自己终止
    • 如果T的时间戳 > S的时间戳(T是刚启动的新事务):T直接主动终止(也就是“die”),之后可以带着原来的时间戳重试
  • 为什么能解决你的饥饿问题?拿你的场景举例:T1第一次被终止后重试,它的时间戳还是原来的老时间戳,比后来的T3、T4、T5都小。当T1再请求锁时,T3作为新事务(时间戳更大)会主动die,而不是让T1被牺牲。这样T1总有机会等到锁,完成执行。
Wound-Wait 算法

这是一种“抢占式”的冲突处理逻辑,核心是老事务直接抢占,新事务乖乖等待:

  • 同样,每个事务启动时分配递增时间戳,老事务时间戳更小
  • 当事务T请求被事务S持有的锁时:
    • 如果T的时间戳 < S的时间戳(T是老事务):T直接终止S(也就是“wound”S),S释放锁后T立刻获取锁;S之后可以带着原时间戳重试
    • 如果T的时间戳 > S的时间戳(T是新事务):T等待,直到S释放锁或者S被其他老事务终止
  • 对应你的场景:T1重试后时间戳还是比T3小,当它请求锁时,直接把T3终止掉,自己拿到锁继续执行,根本不会再被当成牺牲者。
两种算法的核心共性

不管是Wait-Die还是Wound-Wait,本质都是靠全局有序的时间戳来固定事务的优先级:老事务的优先级永远高于新事务,不会出现新事务一直“欺负”老事务的情况,从根源上杜绝了饥饿问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:32:56