7

我正在寻找一个需要在不可靠网络中工作的系统的 Hibernate。我们需要对一个中央数据库进行读写访问,但它可以通过一个相当不完整的 wi-fi 网络访问。此外,可能存在无法彻底关闭应用程序的电源损耗,因此任何解决方案都必须具有能够在电源循环后继续存在的持久缓存。最后,这是一个只有适度内存和磁盘空间的嵌入式系统,因此例如对数据库进行全面复制不是一个可行的策略。

我对 Hibernate 2nd Level 缓存有一个基本的了解,我想知道是否可以用 Ehcache 之类的东西来配置它来解决这个问题,但主要的目的似乎是性能而不是可用性,所以我不知道陷阱可能是什么。

我也非常愿意考虑涉及复制到本地数据库的其他策略。我宁愿自己不必做太多繁重的工作来实现这一点。

寻找一些经验或可能的替代方案。

4

6 回答 6

3

“此外,可能存在无法彻底关闭应用程序的电源损耗,因此任何解决方案都必须具有能够在电源循环后继续存在的持久缓存。”

您已经有了使用 Hibernate 2 级缓存的解决方案。但是你没有说真正的要求是什么。你有一个不可靠的网络。没关系,你的电源不可靠。那也没关系。现在你想达到什么水平的服务?什么是可以接受的?

数据丢失是否可以接受?你能接受多少?你接受什么风险?

更明确地说,假设您有数据库的本地副本或至少有一部分。假设您知道如何排队/保存本地所做的修改。假设您将这些修改存储在硬盘驱动器上,以防断电。假设您可以在连接再次可用时将更改与主数据库合并。

这已经是很多假设了。好的,但是如果一个硬盘驱动器在电源故障后发生故障怎么办?您知道硬盘不喜欢断电,而且往往会在断电时损坏甚至损坏吗?

所以你装上一个RAID,并添加一个不间断电源。那很好。您从操作系统检测电源故障事件。完成您当前的交易并正确关闭。您的 RAID 保护您免受磁盘故障的影响。

好的,但是如果整个计算机停止运行会发生什么?万一发生火灾怎么办?还是水害?所有磁盘都将被管理,数据不可恢复,与中央数据库不同步的数据将丢失。是否可以接受?

即使打开wifi,电源也能正常工作……中央数据库的可靠性到底是多少?你有定期备份吗?还是集群解决方案?你确定你的中央数据库是可靠的吗?

从数据库的角度来看,很容易使用集群或备份并使用事务来确保数据一致性。您仍然可以丢失数据(如果不特别使用集群),但您应该能够恢复到上次备份,例如。

但是如果你想离线工作(数据库不可用),并且你不是唯一可以修改数据库的人,就会发生冲突。这不再是缓存、休眠或任何技术问题。

这是功能问题。当离线发生多次修改并且您必须合并时该怎么办?什么是可以接受的?什么不是。这可能是在重新连接时,应用最新的更改,旧的更改被丢弃。或者检测到潜在的冲突并提示用户处理它们。您可以尝试应用排队更改并应用所有更改...

我倾向于认为您可以提供“离线模式”,但您的用户必须知道他们处于离线状态,并且应该在中央数据库上永久更改并最终解决冲突时收到通知。但这是我的观点。

于 2011-05-09T00:20:34.043 回答
2

你不能指望在hibernate和数据库之间建立一个这样的网络。

我建议您定义一组高级原子操作,然后为它们定义一组(例如)restful 服务。或者,如果您愿意,您可以使用soap 并查看WS-* 选项以获得可靠的消息传递,以处理重试和所有其他混乱的细节。

或者,您可以调查链接中的 cassandra 之类的东西是否会比 SQL 工作得更好,或者其他在复制方面大的东西。

于 2011-04-30T23:18:24.250 回答
2

如何在持久/持久消息队列上排队数据库操作,并让一些消息中间件处理网络问题?

根据您的操作方式,可能会出现一致性问题(好吧,我猜“异常”是正确的词),但是如果您的网络不可靠并且仍然需要良好的性能,那么解决宽松的一致性可能是要走的路。

我会犹豫是否使用 EhCache 等。它们不是为此而设计的,因此您可能必须“拉伸”框架。另一方面,消息队列具有专为此类场景设计的解决方案。

于 2011-05-01T01:23:08.893 回答
1

如果只是两台机器之间的零星连接,我建议保留一个可以回放的事务日志,并将每个条目标记为已处理。不过,有限的内存可能会让这变得困难。

不过,也许您可​​以存储压缩的事务日志。

于 2011-05-01T00:34:45.187 回答
1

Hibernate(和二级缓存)确实不是为此而设计的。我的猜测是,您最好使用小型嵌入式 Java RDBMS(例如 H2 或 HSQLDB)作为本地临时队列(以可用的最持久模式),然后与后台线程进行同步。然后,您可以提供一个连接到该后台线程的同步微调器 UI,以为用户提供某种程度的反馈。

顺便说一句,将 Hibernate 转储到嵌入式环境中有点胖。您可能想考虑使用 myBatis。

于 2011-05-11T17:11:29.263 回答
0

Daffodil Replicator (http://enterprise.replicator.daffodilsw.com/index.html) 允许在 JDBC 源之间进行复制。它支持双向更新、合并和冲突解决以及部分副本。

这可用于将主数据库与本地(部分)副本同步。您可以使用 hibernate 与本地副本数据库通信,并在该过程之外完成其他所有操作。

于 2011-05-15T17:00:06.293 回答