Hibernate 休眠服务器端还是在Swing应用程序的每个实例上?

Hibernate 休眠服务器端还是在Swing应用程序的每个实例上?,hibernate,postgresql,ehcache,Hibernate,Postgresql,Ehcache,我想知道对于现有的重载swing应用程序,什么是最佳设计。 这个应用程序需要一个数据库访问(新),我正在使用hibernate 此应用程序在许多计算机上运行,只需几件事: 能够“锁定”记录以进行修改(其他实例将无法编辑记录),但我必须找到一种方法来防止由于崩溃或其他原因而锁定记录 能够从数据库更新事件中得到通知(我正在使用posrgresql,也许它会有所帮助) 所以我的问题是:我必须在哪里实例化hibernate?在每个应用程序实例上?或者一个唯一的实例“服务器端”,必须编写协议机制(RM

我想知道对于现有的重载swing应用程序,什么是最佳设计。 这个应用程序需要一个数据库访问(新),我正在使用hibernate

此应用程序在许多计算机上运行,只需几件事:

  • 能够“锁定”记录以进行修改(其他实例将无法编辑记录),但我必须找到一种方法来防止由于崩溃或其他原因而锁定记录
  • 能够从数据库更新事件中得到通知(我正在使用posrgresql,也许它会有所帮助)
所以我的问题是:我必须在哪里实例化hibernate?在每个应用程序实例上?或者一个唯一的实例“服务器端”,必须编写协议机制(RMI?EHCache Distributed?…)

服务器模型的问题是,我必须编写Mecanism代码来检测应用程序关闭/崩溃


谢谢。

要回答您的总体问题,我们首先需要探讨数据库交互有多重的问题

通常,在JavaEE上下文中,建议的做法是将所有数据库交互保持在服务器上,并设计一个有用、可用的远程接口,您可以通过EJB访问该接口。但是,此操作过程假设将高级目标从客户端传输到服务器并在那里执行所有处理(换句话说,是服务API而不是数据API)的成本较低

检查JavaEE中推荐的使用模式通常是有用的,因为其中经常有隐藏的提示。例如,使用EJB,您可以将应用程序服务器视为所有数据修改的网关。这将为您提供更多的控制,并允许您将通常需要自己完成的大量工作(如管理事务)卸载到容器上。它也在很大程度上缓解了对奇特锁定策略的需求

从并发性的角度来看,每种方法都有利弊

服务器端专业人员

  • 无需担心与客户端的缓存同步
  • 简化的事务处理
  • 大量现有基础设施(EJB)
  • 恶意客户端无法直接访问数据库(例如,客户端无需拥有数据库密码)
客户端专业人员

  • 没有分离对象或数据传输对象问题
  • 简化编程模型
  • 不需要花哨的JavaEE应用服务器
通过对要锁定的行发出
选择更新
。这将防止其他进程针对已锁定的行发出
UPDATE
s或
DELETE
s。然而,这是一个明确的代码气味。PostgreSQL具有非常强大的并发处理算法。一般来说,我发现想要显式处理数据库中的锁的人通常不了解数据库如何处理并发性,这几乎总是会带来痛苦。因此,在进行需要显式锁定的应用程序设计之前,您应该问自己一些问题:为什么要锁定数据?为什么我担心其他进程同时访问这些行?其他进程同时更新这些行真的不好吗?我经常发现,这表明应该有另一个实体,而行应该由特定的用户拥有

另一个要点是,PostgreSQL中的锁只有在事务打开时才有效。长时间运行事务是一个非常糟糕的主意,因为它们增加了死锁的可能性。如果PostgreSQL检测到死锁,它将选择其中一个连接并将其杀死,并且杀死您想要的连接的几率非常低。Hibernate也讨厌长时间运行的事务。如果您想将对数据库的访问转移到Swing客户端,那么您计划允许非常长时间运行的事务的可能性非常大,可以直接使用PostgreSQL显式执行,也可以通过长时间保持Hibernate会话或EntityManager打开来隐式执行。这些都是非常糟糕的想法,会带来大量内存开销和并发问题的空间

此外,如果Hibernate与手动获取的锁配合得很好,我会大吃一惊。一旦Hibernate与您的数据库相关,我认为期望保留对数据库方面与事务有关的任何数量的控制是一个非常糟糕的想法。Hibernate真的希望拥有这个进程,从某种意义上说,它是为了自己的目的而劫持它的;用同一个连接直接胡闹迟早会导致疼痛

从所有这些坏消息中,有两条好消息可以挽救:

  • 可用于在不同进程之间同步的。我不知道人们会如何在Hibernate中使用它
  • PostgreSQL保留锁的时间不会超过事务的持续时间。如果您的连接获得锁,然后断开连接,则该锁将被没收。你不必为此担心。(即使情况并非如此,PostgreSQL也会注意到死锁并杀死其中一个事务以允许工作继续进行)
如果您决定允许分布式客户端通过长时间运行的事务直接访问数据库,您可能需要使用进行调查。这是一种有效地保持一组分布式进程共享缓存的方法

总之

从问题的措辞来看,似乎您希望在使用Hibernate的同时对数据库进行大量的显式控制。这向我表明,存在需求的混乱。Hibernate是一个数据库抽象层;它是关于隐藏你积极感兴趣的各种细节。此外,PostgreSQL itse