MySQL 中 CURRENT_TIMESTAMP 到底取的是 INSERT 时间,还是 COMMIT 时间?

MySQL 中 CURRENT_TIMESTAMP 到底取的是 INSERT 时间,还是 COMMIT 时间?

目录

    • 结论
    • 验证
      • 实验 1:INSERT 后 sleep 10 秒再 COMMIT
      • 实验 2:让 INSERT 语句自身慢 10 秒

一个表的updated_ts字段定义如下:
updated_tstimestampNOTNULLDEFAULTCURRENT_TIMESTAMPONUPDATECURRENT_TIMESTAMP

执行insert 或 update的时候 updated_ts 取的是 INSERT 时间,还是 COMMIT 时间?

结论

先给结论:
updated_ts 取的是 INSERT 语句执行时的当前时间,不是 COMMIT 的时间。
也就是说:

BEGIN;INSERTINTOservicegroup(...)VALUES(...);-- 这里决定 updated_ts-- 中间耗时约 10sCOMMIT;-- 不会重新刷新 updated_ts

如果 INSERT 时没有显式指定 updated_ts,这一列会用:
DEFAULT CURRENT_TIMESTAMP
自动填充。ON UPDATE CURRENT_TIMESTAMP只会在后续UPDATE该行时触发,不会因为事务COMMIT而触发。

所以结论是:

  • updated_ts ≈ INSERT 语句实际执行时的时间
  • 不是事务开始时间,除非 INSERT 就在事务开始时执行
  • 不是 commit 时间
  • 如果 INSERT 本身是长语句,例如 INSERT … SELECT … 跑了 10s,一般按该语句开始执行时的时间取值,同一条语句插入的多行通常时间一致
  • 如果显式写了 updated_ts,则以显式值为准

简单例子:

BEGIN;INSERTINTOdatabase_servicegroup(...)VALUES(...);-- 10:00:00DOSLEEP(10);COMMIT;-- 10:00:10

最终 updated_ts 通常是 10:00:00 左右,而不是 10:00:10。

验证

临时表:

CREATETABLEcodex_updated_ts_test(idINTNOTNULLAUTO_INCREMENTPRIMARYKEY,nameVARCHAR(50)NOTNULL,updated_tsTIMESTAMPNOTNULLDEFAULTCURRENT_TIMESTAMPONUPDATECURRENT_TIMESTAMP);

实验 1:INSERT 后 sleep 10 秒再 COMMIT

结果关键数据:

after_insert: 2026-07-10 15:01:15 updated_ts: 2026-07-10 15:01:15 after_commit: 2026-07-10 15:01:25 差值: 10 秒

说明:updated_ts 是 INSERT 时的时间,不是 COMMIT 时间。

实验 2:让 INSERT 语句自身慢 10 秒

执行类似:

INSERTINTOcodex_updated_ts_test(name)SELECT'slow_insert_statement'FROM(SELECTSLEEP(10))s;

结果关键数据:

before_insert: 2026-07-10 15:01:25 after_insert: 2026-07-10 15:01:35 updated_ts: 2026-07-10 15:01:25 差值: 10 秒

结论验证一致:updated_ts DEFAULT CURRENT_TIMESTAMP 在 INSERT 时取的是 INSERT 语句开始执行时刻,不是 INSERT 结束时刻,也不是事务 COMMIT 时刻。