【发布时间】:2015-12-02 11:39:16
【问题描述】:
我正在运行对一个表执行多次更新的事务(可能需要几秒钟),然后对第二个表执行另一次更新。最终更新的时间戳为 NOW():UPDATE KeyTimestamps SET timestamp=NOW() WHERE key=$key。
我担心更新以一种顺序发生,但时间戳看起来像是以另一种顺序发生的。这样我们就有了如下的表状态序列:
key | timestamp
----+--------------------
A | 1970-01-01 00:00:00
B | 1970-01-01 00:00:00
key | timestamp
----+--------------------
A | 2015-12-02 12:00:00
B | 1970-01-01 00:00:00
key | timestamp
----+--------------------
A | 2015-12-02 12:00:00
B | 2015-12-02 11:59:59
这会发生吗?手册says
NOW() 返回一个常数时间,指示语句开始执行的时间。
但是一个查询可以先于另一个开始执行,然后再完成执行吗?交易可以保护我免受这种情况的影响吗?
【问题讨论】:
-
一般来说是可以的。您需要更具体地了解哪个线程运行什么,以获得更具体的答案。
-
有什么替代方案?您可以在 MySQL 之外生成该值并将其作为常量参数传递给 UPDATE 语句 - 在锁争用的情况下,这将导致基本相同的问题。唯一真正的替代方案是消除争用的可能性,因此语句顺序执行,而不同时运行其他语句。
-
如果我不需要它作为时间戳,还有其他选择吗?例如。带有 auto_increment col 的表 Monotone 怎么样。在一个事务中:许多更新;
INSERT INTO Monotone () VALUES ();UPDATE KeyMonotones SET key='A', monotone=LAST_INSERT_ID()。 (或者在 Monotone 中只有一行,UPDATE Monotone SET val=LAST_INSERT_ID(val+1)。)这会安全吗/有更简单的方法吗?
标签: mysql transactions timestamp