有时离线应用架构问题

时间:2008-12-16 09:04:39

标签: architecture replication n-tier-architecture offline

我有一个针对sqlserver DB运行的n层winform客户端服务器应用程序。我希望它能够有时运行“离线”(未连接到数据库)并重新连接,重新对主数据库进行更改。现在,我有一个艰难的架构决策:我应该使用数据库复制还是自己使用队列/脚本等管理它。我的应用程序退出复杂 - 我使用数据库与表包含自动增量键和表之间的forien键约束。我的部分数据没有嵌入数据库中,如图片和文档。我非常想听听你的意见和过去的经历!谢谢,阿迪

5 个答案:

答案 0 :(得分:2)

免责声明:我假设您已经考虑过使用.NET数据集并对其进行打折,因为它们旨在帮助解决您遇到的问题域'重新描述。)

我曾经为一家为其全国连锁店开发销售点系统的公司工作。主数据库存储在总部,而每个商店都有自己的该数据库的缩减版本存储在该站点的本地。实际上,每个商店都是脱机的,所以这并不是你所描述的情况,但是我们必须处理一些我认为你需要处理的同步/复制问题。

我们的数据通信每晚都会发生:商店将在预定的时间连接到总部,上传一组数据更改,并下载要应用于该商店本地数据库的类似数据包更改。然后,我们在两个站点(总部和商店)都拥有了您可能称之为“数据同步引擎”的东西,这些站点将处理这些数据包,将更改(插入/更新/删除)折叠回相关数据库。

当您执行此类基本数据复制时,Sergio提到了许多潜在的陷阱。一个是标识,即如何派生唯一标识表行的主键。另一个是版本控制,以及如何处理同一行的不同版本之间的冲突。

在我们的例子中,我们通过使用GUID作为主键而不是使用自动增量列来为自己简化(-ier!)。使用GUID并非没有问题,但在我们的例子中,它意味着我们可以为新数据行分配主键,而不必担心其他人使用它。

我对如何处理版本控制问题有点模糊(已经有几年了!),但是从内存中我认为每个表行都有两个时间戳:其中一个记录了行的日期/时间在总公司更新;另一个,当它在商店更新。每行还有两个“版本号”,表示总行和商店的行版本。数据协调涉及将这些时间戳和版本号相互比较,最近的更改为“获胜”(假设对方没有改变当然的行)。

正如Sergio指出的那样,您最大的问题是处理数据协调冲突。在我们的案例中,这发生在商店和总部在同一天更改了相同的数据项时。我们总是通过在商店端改变失败并在总部编写自定义数据协调应用程序来解决这个问题,其中涉及用户在视觉上比较和合并数据项的两个冲突版本。从理论上讲,我认为您可以使用一些自定义处理规则自动合并不同版本,但是您需要权衡开发此类内容的成本与发生冲突的可能性。从内存来看,尽管存在大量商店(数百家)对同一组数据进行更改,但这对我们的系统来说从未被证明是一个大问题。 YMMV当然。

答案 1 :(得分:0)

我之前从未做过这样的事情,但在我看来,如果你这样做,你可能会遇到严重的问题......

从技术上讲,我认为实施起来并不困难。基本上,您必须在每个客户端上设置数据库的副本,并在每次客户端连接到服务器时与服务器同步,但我猜您已经达到了这一点。

我会在客户端的每个表上都有一个列和一个日期戳,这样我就可以检查哪些记录已经脱机更改了。在服务器端,用于记录对象上次更新的日期戳列将起到作用。

对于具有自动增量的主键,我会松开它们,因为您需要自己设置它们以防止使用相同的键创建两个记录(您可能需要在同步时更改它们)。

这是容易的部分......现在是事情会变得混乱的地方......你需要考虑到这会给你带来很多麻烦......所有种类或不期望的事件都会发生,一些例子: - 两个用户离线更改相同的记录。 - 一个用户在线更改记录,另一个用户更改离线记录 - 一个用户在线删除记录而另一个用户离线记录

潜在问题列表一直在继续,在你开始解决这些问题之前,你必须列举每一个问题并向客户提供文件,告诉他们系统如何处理每个案例,否则当他们丢失数据时(这将会发生无论你做什么,这都是你的错,而不是他们的。

我建议您为数据库中可以离线更改的每个表构建一个版本控制系统。用户将弄乱他们的数据,他们将很好地执行回滚。

答案 2 :(得分:0)

我现在已经在不同的地方做过好几次了(请参阅Steve Rands的回答)我强烈建议你不要使用正常的复制 - 特别是如果涉及多个数据库的话。

我说这个的原因是,根据我的经验,复制不够聪明,无法解决当您将远程站点重新联机时(或者当您决定将新站点添加到整个网络时)可能出现的问题

如果您只有2个或3个不同的数据库,但是如果您正在谈论可以随时在线/离线的许多不同位置,并且可以添加(或删除或修改)信息,则复制适用于此类事情)在任何一个地方,你都不会花很长时间才能把事情搞得一团糟。这说起来并不是一件非常令人满意的事情,但你总是能够想到一些特殊的情况,你不希望复制按照设计的意愿去做。

如果您只处理2个数据库,那么显然复制问题变得更加简单,您可能会发现可以使用合并复制来完成工作(尽管您必须观察数据库设计)。

我刚刚购买了Apress SQL Server 2005复制圣经的二手​​副本(不在办公室,所以没有作者可以提供,但它是一个推荐的,怪物书) - 在第一对夫妇内章节我开始意识到,如果你真的在两个(或更多)端改变数据,那么复制不是一个神奇的解决方案。 :-)

答案 3 :(得分:0)

这通常称为公文包模型,可以使用 Microsoft Synchronization Services for ADO.NET

答案 4 :(得分:0)

您应该查看Microsoft Sync Framework

从头开始构建偶尔离线的解决方案是一项复杂的任务。在我的职业生涯中,我看到许多优秀的开发团队搞砸了。我不是说你自己建造它会有问题,但为什么不使用已经存在的东西呢?如果您发现它无法满足您的需求,您可能会更好地了解如何编写自己的解决方案。

权衡是你必须学习同步框架,但有些样本你可以立即利用。