gpt4 book ai didi

hibernate - 如何使用 Spring 和 Hibernate 为 Web 应用程序和批处理作业设置事务

转载 作者:行者123 更新时间:2023-12-04 19:20:37 24 4
gpt4 key购买 nike

我有一个使用 Spring 2.5 和 Hibernate 3 的应用程序。

有一个带有表示层、服务层和 DAO 层的 Web 应用程序,以及一些共享相同服务和 DAO 层的 Quartz 作业。

事务在不同的层中使用 @Transactional 注释进行初始化,如下所示:

alt text

它导致我在这里描述的一个问题:Controlling inner transaction settings from outer transaction with Spring 2.5

我阅读了一些关于如何设置事务以将 Spring 和 Hibernate 连接在一起的内容。看起来推荐的方法是在服务层初始化事务。

我不喜欢的是大多数事务的存在只是因为它们是 hibernate 正常工作所必需的。

当我真的需要一个调用多个服务方法的作业的事务时,似乎我没有选择继续从作业初始化事务。因此,将 @Transactional 注释从 DAO 移到服务似乎没有任何区别。

您建议如何为此类应用程序设置事务?

最佳答案

I read a bit about how to set-up transactions to wire Spring and Hibernate together. It looks the recommended approach is to initialize transactions in the service layer.



确实。事务划分应该在服务层级别完成,而不是在 DAO 层级别:
  • 工作单元是服务,而不是 DAO
  • 如果需要,您希望事务跨越多个 DAO。

  • What I don't like is that most transactions exist only because they are required for hibernate to work properly.



    您可能应该详细说明这一部分,因为事务不是特定于 Hibernate 的。

    And when I really need a transaction for a job calling multiple service methods, it seems I don't have a choice to keep initializing transactions from the jobs.



    如果您想在从作业层发起的事务中调用多个服务,请使用 REQUIRED 将您的服务声明为事务性的。语义(默认)并依赖 Spring 事务传播(除非您需要远程调用,否则这适用;在这种情况下,请使用 EJB)。

    So moving @Transactional annotations from DAO to service doesn't seem to make any difference.



    有所不同,并且在运行批处理时您需要从作业层启动事务这一事实并没有使事情有所不同。

    我热烈推荐阅读 Chapter 9. Transaction management .

    (...) my main problem comes from Hibernate. Sorry if I wasn't clear.



    没问题。只是当问题含糊不清时,您往往会得到含糊的答案:)

    From hibernate documentation: "Database transactions are never optional. All communication with a database has to occur inside a transaction.". That's why developers put DAO methods transactional on my project.



    抱歉,上面的语句只说“与数据库的通信必须发生在 内部 事务中”,仅此而已,决定从哪里开始事务由您决定(通常是服务层)。如果你在 DAO 级别做,如果 MySuperService 怎么办?电话 DaoFooDaoBarDaoBar失败?在这种情况下,您可能希望回滚所有更改,而不仅仅是在 DaoBar 中执行的更改。 .因此需要控制工作单元开始的事务。

    恕我直言,开发人员需要一些指导。

    Does that mean all my services should be transactional? Even when I just read data for example?



    首先,我建议阅读 Non-transactional data access and the auto-commit mode ( Sessions and transactions 的弟弟)澄清有关“只读交易”的事情。阅读整页是值得的,但让我引用这一特定部分:

    Many application developers think they can talk to a database outside of a transaction. This obviously isn’t possible; no SQL statement can be send to a database outside of a database transaction. The term nontransactional data access means there are no explicit transaction boundaries, no system transaction, and that the behavior of data access is that of the autocommit mode. It doesn’t mean no physical database transactions are involved.



    完成上述链接后,下一个建议阅读将是 @Transactional read-only flag pitfalls .这是相关部分:

    (...) The bottom line is that when you use an ORM-based framework, the read-only flag is quite useless and in most cases is ignored. But if you still insist on using it, always set the propagation mode to SUPPORTS, as shown in Listing 9, so no transaction is started:

    Listing 9. Using read-only and SUPPORTS propagation mode for select operation

    @Transactional(readOnly = true, propagation=Propagation.SUPPORTS)
    public TradeData getTrade(long tradeId) throws Exception {
    return em.find(TradeData.class, tradeId);
    }

    Better yet, just avoid using the @Transactional annotation altogether when doing read operations, as shown in Listing 10:

    Listing 10. Removing the @Transactional annotation for select operations

    public TradeData getTrade(long tradeId) throws Exception {
    return em.find(TradeData.class, tradeId);
    }

    关于hibernate - 如何使用 Spring 和 Hibernate 为 Web 应用程序和批处理作业设置事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3882994/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com