【问题标题】:Hibernate, Spring Web Service transaction issueHibernate,Spring Web Service事务问题
【发布时间】:2011-04-15 05:35:44
【问题描述】:

我有两个应用程序。一个是 OrderService,另一个是 TradeService。 在贸易服务中,有一种“购买”方法是交易性的。

Trade Service 使用 Web Service 调用 Order 服务的 SubmitOrder 方法时出现问题。

问题描述:

  1. Buy 方法中的所有步骤都在一次交易中。

  2. 当我们调用 buy 方法时,它会创建一个 Order 对象。

  3. 当这个方法使用web service调用Submit Order方法时,它会传递order Id。

  4. 提交订单方法使用此 Id 从数据库加载订单对象。

  5. 但是在 Load 方法中它给出了延迟初始化异常:会话已关闭。 (两个应用程序共享同一个数据库)

  6. 对此的可能解决方案是使提交订单方法具有事务性。

  7. 这会导致另一个死锁问题。

    • 死锁的原因, A. Buy 方法锁定 Id 为“xyz”的订单对象。并发送相同的 ID 提交订单方法。 B. 现在 Buy 方法正在等待提交订单的回复。 C. Submit Order 方法无法加载 order 对象,因为它已经被 buy 方法锁定。 D. 所以提交订单方法正在等待获取锁。因此它是死锁条件。

注意:这两个应用程序都使用 Spring MVC、Spring Web Service 和 Hibernate。

请帮助我摆脱这种情况。提前致谢。(如果需要,我可以发布部分代码)

【问题讨论】:

  • 您是否尝试围绕 Web 服务调用构建数据库事务?
  • 是的。 Web 服务调用仅来自购买方法。
  • 您期望在 Web 服务(订单)的另一端可以使用相同的事务?
  • 是的。 Buy中的所有东西都应该在一笔交易下。但这是不可能的,这种情况不允许我将提交订单方法(订单服务)进行交易。

标签: hibernate spring spring-mvc spring-ws hibernate-annotations


【解决方案1】:

一般来说,不可能在 Web 服务调用的两端使用相同的数据库事务。 -- 至少根本不可能通过网络服务传输连接。

因此,您必须接受这样一个事实,即您有/需要两个数据库事务。每边一个。 - 除此之外(这会导致您的延迟初始化异常),如果 Web 服务 - 服务器端接收一个实体,它不会附加到任何会话,所以如果您尝试访问尚未加载(layz 加载)的属性然后得到这个layz加载异常。

您需要做的是,打开一个事务,并首先将实体附加到该事务。

【讨论】:

  • 但是当我创建两个事务时,它会导致死锁情况。请参阅有问题的第 6,7 点。
  • @Sagar 我认为您必须重新考虑完整的结构。我是我谦虚的选择,它有一种非常难闻的气味。 - 例如:事务和锁应该尽可能短,Web 服务的调用显然比事务或锁应该花费的时间更长。 -- 下一步:你应该有明确的责任,哪个模块负责哪个对象。 -- 下一步:这并不是真正的死锁,它只是一个事实(取决于隔离级别),在订单创建的事务提交之前,订单对于其他事务不存在。
  • @Sagar:我强烈建议让它变得更简单。创建订单的服务器必须存储它。可能您必须将订单(实体)和订单数据(DTO 模式)分开。然后客户端可以创建 OrderD 发送给 Order Server,Order Server 从 DTO 构造一个 Order Entity 并保存。 - 或者订单服务器可能只对 DTO 起作用,而购买服务器在 Web 服务调用完成后创建订单实体。
【解决方案2】:

TradeService 为什么要创建订单?我希望这是 OrderService 的责任。这样就不会出现对同一资源的争用。

是的,这两种服务都应该是事务性的。您收到 LazyInitializationException 是因为您的加载方法可能会进行 2 次单独的数据库调用来构建 Order 实例,并且会话在第一次数据库调用后关闭。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-26
    • 2011-08-23
    • 2010-11-16
    • 2011-06-13
    • 2020-06-13
    相关资源
    最近更新 更多