2

在我正在开发的系统上,我们有一个 PostgreSQL 数据库,其中包含设置数据,当这些手机“对接”时,更新时必须将其传输到手机。当手机插接时,我们的“服务软件”可以与它们通话,但在它们未插接时不能(它们不是无线的)。

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

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

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

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

我对这种方法的唯一问题是它意味着数据库正在存储非以业务为中心的数据——因为它正在存储数据以使系统正常工作。我不相信关于哪些手机同步的数据是“商业”数据。对我来说,手机服务软件/手机软件有更多的责任知道如何让自己保持最新,尽管它很诱人,因为它完美地描述了每部手机上的数据是什么,什么不是,并且允许查询只返回数据需要。

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

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

想法?

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

谢谢。

4

1 回答 1

0

首先,如果您使用的 PostgreSQL 版本至少为 7.2,则该now函数以微秒精度而不是秒精度返回值;尽管该值最终是从操作系统中得出的,并且精度最高只有百分之几秒。

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

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

我不能推荐这个,原因如下:

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

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

于 2012-07-01T21:50:55.480 回答