首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >MS日期时间精度问题

MS日期时间精度问题
EN

Stack Overflow用户
提问于 2010-04-12 08:10:27
回答 7查看 9.7K关注 0票数 8

我遇到的情况是,两个人可能在两台不同的计算机上按相同的顺序工作(存储在MS数据库中)。为了防止数据丢失,在这样的情况下,一个人将首先保存他的订单副本,然后第二个将保存他的副本并覆盖第一个,我在保存之前添加了一个针对lastSaved字段(datetime)的检查。

代码大致如下所示:

代码语言:javascript
复制
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在本地副本和DB中的值现在应该是相同的。但是,如果orderIsChangedByOtherUser再次运行,它有时会返回true,即使没有其他用户对DB进行更改。

在Visual中调试时,databaseOrder.LastSaved和localOrderCopy.LastSaved的值似乎是相同的,但仔细看时,它们有时相差几毫秒。

我发现这篇文章在SQL中对datetime的毫秒精度做了一个简短的说明:

另一个问题是Server存储日期时间的精度为3.33毫秒(0毫秒)。00333秒)。

对于这个问题,我能想到的解决方案是比较这两个日期时间,如果它们的差值小于10毫秒,则将它们视为相等。

那么,我对您的问题是:是否有更好/更安全的方法来比较MS中的两个日期时间值,看看它们是否完全相同?

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2010-04-12 10:01:57

我知道您说过不能更改类型,但是如果这只是为了维护兼容性&使用2008年,您可以将lastSaved字段更改为DATETIME2 (与DATETIME完全兼容),并使用SYSDATETIME(),两者都具有更高的精度。

票数 7
EN

Stack Overflow用户

发布于 2010-04-12 08:32:07

可以向order表中添加整数修订字段。每次用户保存订单时,您都会将修订增加一次。然后很容易检查某人是否更改了订单,或者想保存订单的用户是否在最新的版本中。

票数 2
EN

Stack Overflow用户

发布于 2010-04-12 09:12:17

虽然您在SQL 2005和之前的准确性问题将始终存在,从来没有比1/300秒,或3.33ms更准确。

尽管缺乏准确性,但您正在编写一种有缺陷的竞赛条件,在这种情况下,两个用户仍然可以快速地写入数据库,但两者都被认为是成功的。准确性的缺乏增加了发生这种情况的机会,只要检查和后续写入发生在相同的3-4 ms内。

任何在写之后进行检查的尝试都会遇到这个问题,您要么必须接受乐观锁定的后果,要么将锁定更改为pessemistic,要么实现某种形式的信号量类型策略来正确处理锁定。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2620627

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档