我遇到这样的情况,两个人可能在两台不同的计算机上以相同的顺序工作(存储在MS SQL数据库中)。为了防止数据丢失,在这种情况下,一个人先保存订单的副本,然后再稍等一会再保存他的副本并覆盖第一个副本,我在保存之前对_lastSaved_ 字段(日期时间)添加了一个检查。
该代码大致如下所示:
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; } }
这在大多数情况下都有效,但是我发现了一个小错误。
如果 orderIsChangedByOtherUser 返回 false ,则本地副本会将其 lastSaved 更新为当前时间,然后将其持久化到数据库中。现在,本地副本和数据库中的 lastSaved 的值应该相同。但是,如果再次运行 orderIsChangedByOtherUser ,则即使没有其他用户对数据库进行更改,有时也会返回 true 。
在Visual Studio中进行调试时, databaseOrder.LastSaved 和 localOrderCopy.LastSaved 似乎具有相同的值,但是当仔细观察时,它们有时相差几毫秒。
我发现这篇文章对SQL中日期时间的毫秒精度有一个简短的通知:
另一个问题是SQL Server以3.33毫秒(0. 00333秒)的精度存储DATETIME。
对于这个问题,我能想到的解决方案是比较两个日期时间,如果它们之间的差异小于10毫秒,则认为它们相等。
那么我想问的是:是否有更好/更安全的方法来比较MS SQL中的两个日期时间值,看它们是否 完全相同 ?
我知道您说过您不能更改类型,但是如果这仅仅是为了保持兼容性并且您使用2008年,就可以将lastSaved字段更改为DATETIME2(与完全兼容DATETIME),并使用SYSDATETIME()两者都具有更高的精度。
lastSaved
DATETIME2
DATETIME
SYSDATETIME()