Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MS SQL datetime precision problem

I have a situation where two persons might work on the same order (stored in an MS SQL database) from two different computers. To prevent data loss in the case where one would save his copy of the order first, and then a little later the second would save his copy and overwrite the first, I've added a check against the lastSaved field (datetime) before saving.

The code looks roughly like this:

private bool orderIsChangedByOtherUser(Order localOrderCopy)
{
    // Look up fresh version of the order from the DB
    Order databaseOrder = orderService.GetByOrderId(localOrderCopy.Id);

    if (databaseOrder != null &&
        databaseOrder.LastSaved > localOrderCopy.LastSaved)
    {
        return true;
    }
    else
    {
        return false;
    }
}

This works for most of the time, but I have found one small bug.

If orderIsChangedByOtherUser returns false, the local copy will have its lastSaved updated to the current time and then be persisted to the database. The value of lastSaved in the local copy and the DB should now be the same. However, if orderIsChangedByOtherUser is run again, it sometimes returns true even though no other user has made changes to the DB.

When debugging in Visual Studio, databaseOrder.LastSaved and localOrderCopy.LastSaved appear to have the same value, but when looking closer they some times differ by a few milliseconds.

I found this article with a short notice on the millisecond precision for datetime in SQL:

Another problem is that SQL Server stores DATETIME with a precision of 3.33 milliseconds (0. 00333 seconds).

The solution I could think of for this problem, is to compare the two datetimes and consider them equal if they differ by less than say 10 milliseconds.

My question to you is then: are there any better/safer ways to compare two datetime values in MS SQL to see if they are exactly the same?

like image 887
Julian Avatar asked Apr 12 '10 08:04

Julian


People also ask

How do you fix the conversion of a varchar data type to a datetime data type resulted in an out of range value?

Answer: The error is due to an invalid date format being saved to the custom_rmh_rooms_history SQL table. To resolve this issue, the Windows Regional settings need to be modified and the Short Date format needs to be in MM/dd/yyyy format.

What is the default datetime format in SQL Server?

SQL Server comes with the following data types for storing a date or a date/time value in the database: DATE - format YYYY-MM-DD. DATETIME - format: YYYY-MM-DD HH:MI:SS.

What is difference between datetime and DATETIME2 in SQL Server?

DATETIME2 has a date range of "0001 / 01 / 01" through "9999 / 12 / 31" while the DATETIME type only supports year 1753-9999. Also, if you need to, DATETIME2 can be more precise in terms of time; DATETIME is limited to 3 1/3 milliseconds, while DATETIME2 can be accurate down to 100ns.


2 Answers

I know you said you can't change the type, but if this is only to maintain compatibility & your using 2008 you could change the lastSaved field to DATETIME2 (which is fully compatible with DATETIME) and use SYSDATETIME() both of which have much greater precision.

like image 183
Alex K. Avatar answered Oct 14 '22 02:10

Alex K.


You could add an integer revision field to your order table. Every time a user saves the order you increase the revision by one. Then its easy to check if somebody has altered the order or if the user who wants to save the order are on the latest revision.

like image 44
Juri Glass Avatar answered Oct 14 '22 01:10

Juri Glass