保持手机与数据库同步

时间:2012-07-01 15:26:10

标签: database database-design relational-database

在我正在开发的系统上,我们有一个PostgreSQL数据库,其中包含设置数据,当这些手机被“停靠”时,必须将更新时的数据转移到手机上。当手机停靠时,我们的“服务软件”可以与他们交谈,但不会在他们未对接时(他们不是无线)。

目前,手机通话的服务软件在启动时从数据库加载设置数据并进行缓存。此后,它每5秒查询一次设置数据的最新时间戳,如果查询的时间戳高于最新的高速缓存时间戳,则重新加载部分设置。

然而,我发现这种方法随意。例如,如果更新事务花费的时间超过一秒,或者至少如果提交事务和事务完成之间的时间超过1秒的边界(now()函数是由PostgreSQL在事务开始时解决)。我能想到的唯一方法就是在查询最新时间戳之前进行表级锁定。我不是表锁的粉丝,但这是我能想到解决问题的唯一方法。

这种方法的另一个问题是,我必须根据更新时间戳查询新数据> =最后一个最新时间戳,而不是仅仅>>最后一个时间戳。为什么?因为记录可能在同一秒内提交,就在我的查询之后 - 所以我会错过记录。

我想到的另一种方法是,在数据库中为必须存储在手机上的每个逻辑数据项存储“最后同步的日期时间”数据。我会在每个手机的基础上这样做。然后,我可以定期查询当前未在特定手机上同步的所有数据,然后在手机处于最新状态时将其标记为已同步(我已经设计了一种机制,使其成为故障保护,考虑到在更新期间更新的数据)同步)。

这种方法的唯一问题是它意味着数据库存储非以业务为中心的数据 - 因为它存储数据以使系统工作。我不相信有关手机同步的数据是“商业”数据。对我而言,手机服务软件/手机软件更有责任了解如何使自己保持最新状态,尽管它很有诱惑力,因为它完美地描述了每个手机上的数据和不存在的数据,并且只允许查询返回数据需要的。

然而,第一种方法至少只使用适合业务的数据 - 即上次更改数据的时间戳。

理想的方法是使用某种通知系统,但不幸的是postgres只有一个基本的NOTIFY / EVENT系统,而且似乎不能通过ODBC(我愚蠢地决定使用并且没有时间到刚刚改变)。如果我使用的是Oracle,我可以使用Streams ..

思想?

注意:数据库纯粹是关系型的 - 我对这个问题或任何基于框架的解决方案的任何“面向对象”方法都不感兴趣。

感谢。

1 个答案:

答案 0 :(得分:0)

首先,如果你使用PostgreSQL版本至少7.2,now函数返回微秒精度而不是第二精度的值;虽然该值最终来自操作系统,但只能精确到几百分之一秒。

您描述的方法似乎可以安全地防止永久丢失任何更新。只需确保每次重新加载数据,除非时间戳证明您在上次更新后已经重新加载了足够长的时间。或者,您可以在单独的事务中更新数据更新时的时间戳;在这种情况下,永远看到这样的时间戳是所有更新在时间戳值之前完成的证据。

  

我想到的另一种方法是,存储“最后同步的   日期时间“数据库中每个逻辑数据项的数据   必须存放在手机上。我会在每部手机上做到这一点   基础。然后我可以定期查询当前没有的所有数据   在特定手机上同步,然后将其标记为已同步   一旦手机是最新的

由于以下原因,我不能推荐这个:

  • 由于同步是手机的状态而不是数据的状态,因此最好将此信息存储在手机上。
  • 数据库应该可以扩展到许多手机,理想情况下不应该跟踪它们。
  • 如果手机可以更改其身份,或者在不改变其身份的情况下擦除或恢复(重新成像)到之前的状态,则数据库将与耳机的真实状态不同步,并且没有任何机制可确保正确同步。

虽然NOTIFY肯定比常量轮询更可取,但与存储同步进度的位置正交是一个问题。您仍然需要具有轮询功能才能处理新连接的设备,而通知只是带宽/延迟优化。