philh
philh

Reputation: 646

How does NOW() interact with transactions?

I'm running transactions which perform many updates to one table (taking perhaps a couple of seconds), and then another update to a second table. The final update is timestamped with NOW(): UPDATE KeyTimestamps SET timestamp=NOW() WHERE key=$key.

I'm worried about updates happening in one order, but with timestamps that look like they happened in the other order. So that we have the following sequence of table states:

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

Can this ever happen? The manual says

NOW() returns a constant time that indicates the time at which the statement began to execute.

but can one query start to execute before another, and finish executing later? Do transactions protect me against this?

Upvotes: 3

Views: 2928

Answers (2)

Gordon Linoff
Gordon Linoff

Reputation: 1269873

This is a bit long for a comment.

If you want to know the ordering of inserts into a table, then use an auto-incrementing column. This is guaranteed to never have duplicates and should be assigned in insertion order. You can then compare this ordering to the ordering using a time stamp column.

Note that the time stamp column could be identical for two rows inserted at the same time.

Upvotes: 2

O. Jones
O. Jones

Reputation: 108676

As the manual says, MySQL binds the value of NOW() at the start of each individual statement. Therefore, if the value is used multiple times inside a statement, it will be the same.

If you need the value bound at the beginning of a multiple-statement sequence (transaction), do this:

SET @start := NOW();
SELECT something;
UPDATE something else;
...
UPDATE KeyTimestamps SET timestamp=@start WHERE key=$key

Each distinct client connection will keep its own values of variables like @start so this will work when you have multiple clients doing the transactions at once.

Beware: operations which you initiate at near-simultaneous times from different clients will run in an order that's formally unpredictable. They won't always run in the order that your intuition tells you they will. So try to avoid depending on the precise order of operations in your system design. The same is true of autoincrementing ids. If you do make your system depend on such things, you're creating the possibility of race conditions. Those are bloody murder to debug.

Upvotes: 3

Related Questions