InnoDB锁等待场景下NOW()与CURRENT_TIMESTAMP取值规则咨询
InnoDB锁等待时NOW()/CURRENT_TIMESTAMP的取值行为
这个问题问得很务实,刚好我在实践中验证过这个场景,也梳理过内部的执行逻辑,给你明确的答案:
当InnoDB引擎下的INSERT/UPDATE语句因为锁等待进入阻塞状态时,NOW()和CURRENT_TIMESTAMP会取语句开始尝试执行(也就是触发锁等待前的那个时间点)的时间值,绝对不是实际拿到锁、执行数据变更操作时的时间。
背后的逻辑
MySQL对这类时间函数的处理是语句级初始化时确定值:当你提交一条INSERT/UPDATE语句,MySQL在语句执行的初始化阶段就会解析并获取当前系统时间,把这个值绑定到语句中,后续不管这条语句因为锁等待、IO延迟等原因卡多久,这个时间值都不会再更新。
举个直观的例子:
假设你在10:00:00执行这条语句:
UPDATE user SET last_update = NOW() WHERE id = 100;
此时刚好有另一个事务持有id=100的行锁,这条UPDATE进入锁等待状态,直到10:05:00才拿到锁完成更新。那么last_update字段存储的时间会是10:00:00,而不是实际执行变更的10:05:00。
额外提醒(避免混淆)
别和SYSDATE()搞混——SYSDATE()是取函数实际执行时刻的时间,不过这个函数在业务场景里很少用,大部分业务场景用的NOW()/CURRENT_TIMESTAMP都是遵循语句启动时间的规则。
内容的提问来源于stack exchange,提问作者Dag Sondre Hansen
相关产品推荐
相关产品推荐

