目录
一个表的updated_ts字段定义如下:
sql
updated_ts timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
执行insert 或 update的时候 updated_ts 取的是 INSERT 时间,还是 COMMIT 时间?
结论
先给结论:
updated_ts 取的是 INSERT 语句执行时的当前时间,不是 COMMIT 的时间。
也就是说:
sql
BEGIN;
INSERT INTO servicegroup (...) VALUES (...); -- 这里决定 updated_ts
-- 中间耗时约 10s
COMMIT; -- 不会重新刷新 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,则以显式值为准
简单例子:
sql
BEGIN;
INSERT INTO database_servicegroup (...) VALUES (...); -- 10:00:00
DO SLEEP(10);
COMMIT; -- 10:00:10
最终 updated_ts 通常是 10:00:00 左右,而不是 10:00:10。
验证
临时表:
sql
CREATE TABLE codex_updated_ts_test (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
updated_ts TIMESTAMP NOT NULL
DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_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 秒
执行类似:
sql
INSERT INTO codex_updated_ts_test(name)
SELECT 'slow_insert_statement'
FROM (SELECT SLEEP(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 时刻。