Hibernate 中的 beginTransaction 是否分配了新的数据库连接?

2022-09-04 01:14:36

只是想知道在Hibernate中开始新事务是否真的分配了与数据库的连接?

我担心b / c我们的服务器会为收到的每个请求开始一个新事务,即使该请求不与数据库交互。我们将数据库连接视为一个主要瓶颈,因此我想知道我是否应该花时间缩小交易范围。

到处搜索,一直找不到好的答案。非常简单的代码在这里:

    SessionFactory sessionFactory = (SessionFactory) Context.getContext().getBean("sessionFactory");
    sessionFactory.getCurrentSession().beginTransaction();
    sessionFactory.getCurrentSession().setFlushMode(FlushMode.AUTO);

非常感谢!一个


答案 1

根据第11.1节。休眠文档的会话和事务范围

A 是一个创建成本高昂的线程安全对象,旨在由所有应用程序线程共享。它通常从实例创建一次,通常在应用程序启动时。SessionFactoryConfiguration

A 是一个廉价的非线程安全对象,应该使用一次,然后丢弃:单个请求、会话或单个工作单元。会话不会获取 JDBC 连接数据源,除非需要。在使用之前,它不会消耗任何资源。Session

为了减少数据库中的锁争用,数据库事务必须尽可能短。较长的数据库事务将阻止应用程序扩展到高并发负载。在工作单元完成之前,不建议在用户认为期间保持数据库事务处于打开状态。

现在,回答您的问题:

  • 获取 a 不会立即获取连接(连接是延迟加载的)Session
  • 但是调用将导致给定连接的负载beginTransaction()Session
  • 后续调用将重复使用相同的connection

查看并浏览代码以获取更多详细信息。org.hibernate.impl.SessionImpl#beginTransaction()


答案 2

(根据Pascal Thivent的评论更新)

如果需要,每个都会创建一个数据库连接 - 例如,如果启动了事务。仅通过创建会话即可打开连接。Session

要解决此问题,可以使用连接池,以便重用连接。或者,您可以确保(就像您所做的那样)不会自动启动任何事务。

(本文讨论只读事务。一起来看看吧。


推荐