【问题标题】:Multiple DAO instances = Bad?多个 DAO 实例 = 不好?
【发布时间】:2011-11-03 12:10:11
【问题描述】:

两个应用程序(A 和 B)使用休眠从数据库中检索相同的实体。应该在每个应用程序中实例化 DAO,还是应该有一个单独的应用程序 (C) 包含 DAO 的唯一实例并公开服务(例如 RMI)供 A 和 B 使用?

如果后一种情况为真,那么防止加载异常的常见做法是什么?我认为我目前的计划是使用 RMI 并为每个域对象创建一个 DTO。我唯一的保留是 A 和 B 中的实体将无法引用 C 中的实体。这是一种常见的策略吗?

可能值得一提的是,有 4 台不同的服务器分别运行 A 和 B。目前每台服务器上也都有数据库 - 出现这个问题是因为我试图集中一些东西 - 要么所有项目都有DAO 指向单个 DB 服务器或所有应用程序都指向由 C 托管的服务,该服务具有指向单个 DB 的 DAO。

【问题讨论】:

  • 我假设“项目”是指“应用程序”?
  • 抱歉,是的,应该是应用程序 - 我会更改它。

标签: java hibernate soa rmi dao


【解决方案1】:

DAO 通常是一个无状态的单例,用于从数据库中加载、搜索、修改和删除实体。为什么要使用 RMI 与另一个 JVM 进行通信只是为了做到这一点?您将严重降低性能,实体将永远不会附加到会话,并且您不能在单个实体上使用跨越多个操作(加载、存储)的事务。只是没有意义。

在每个应用程序中都有一个 DAO 实例。

【讨论】:

  • 我显然错了,所以请原谅我的无知——这不是在 SOA 环境中发生的事情吗?有许多独立的应用程序,其他应用程序可以通过 SOAP/RMI/Hessian 向它们请求数据。独立的应用程序处理 tx、负载平衡、服务认证等
  • 是的,但是您很少需要跨越多个对这些不同 Web 服务的调用的全局事务。对于 DAO,情况并非如此,例如,将资金从一个账户转移到另一个账户需要一次交易来获取账户 A、获取账户 B、从 A 中移除金额、向 B 中添加金额、保存 A 并保存 B。如果你为每次加载和每次保存使用不同的事务,如果其中一个回滚,您将遇到严重的问题。
  • 在您给出的示例中,我将在 C 中使用 AccountService 和方法 transferMoney(Long fromAccId, Long toAccId, Double amount),可以由 A 或 B 调用。可以用帐户;服务可以包含所有这些用例。我的印象是这真的很常见吗?
  • 所以在这种情况下,可以远程访问的不是 DAO,而是实现业务逻辑的功能服务。这是一个完全不同的故事。
  • 好吧,抱歉,我应该更清楚一点——我从来没有打算通过 RMI 公开 DAO。鉴于此,您介意告诉我您对 DTO 方法的看法吗?
【解决方案2】:

您可以使用 spring 并将这个 DAO 实例 bean 添加到两个项目的父应用程序上下文中。

【讨论】:

    【解决方案3】:

    这取决于您的架构。这两种方法都是可行的,各有优缺点。
    如果你有一个 DAO 并通过 RMI / REST 连接到它,你已经使用项目从休眠中解耦,但是引入了一些延迟,对实体施加了可序列化性并且得到了单点故障(可以通过集群解决)

    如果您每个项目都有自己的 DAO,那么您会从休眠配置中获得复杂性,但可以避免延迟和单点故障。

    在这两种情况下,您都应采取预防措施以防止并发数据修改并保持一致性(如乐观锁定等)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      • 2013-04-10
      • 1970-01-01
      • 1970-01-01
      • 2016-12-04
      • 2015-02-24
      相关资源
      最近更新 更多