java 如何使用 Hibernate 处理最大数据库连接?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27897540/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 12:36:09  来源:igfitidea点击:

How to handle max database connections with Hibernate?

javamysqlspringhibernatec3p0

提问by RBP

Below is Hibernate configuration from Hibernate.xml

下面是 Hibernate.xml 中的 Hibernate 配置

    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource">
        <ref bean="dataSource"/>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.hbm2ddl.auto">update</prop>
            <prop key="hibernate.c3p0.timeout">300</prop>
        </props>
    </property>
    <property name="annotatedClasses">
        <list>
         .....
        </list>
    </property>
  </bean>

  <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
   </bean>

Below is code from GenricDaoImpl class (code 1)

下面是来自 GenricDaoImpl 类的代码(代码 1)

@Override
public T save(T t) {
    Session session = getSessionFactory().openSession();
    Transaction tx=session.beginTransaction();
    session.saveOrUpdate(t);
    tx.commit();
    session.close();
    return t;
}

and other code from project (code 2)

和项目中的其他代码(代码 2)

   Query executeQuery = getSession().createQuery(hql);
   UserProfileuser  =  (UserProfile) executeQuery.uniqueResult();

Above both codes I am using in project. My question is which coding need to follow ? code 1 or code 2 to avoid max connections error.? I can connect max 1000 connections with database. But in some cases it is going more than 1000 . So i want to maintain database connection minimum. Please guide me.

以上我在项目中使用的两个代码。我的问题是需要遵循哪些编码?代码 1 或代码 2 以避免最大连接错误。?我最多可以将 1000 个连接与数据库连接。但在某些情况下,它会超过 1000 。所以我想保持最少的数据库连接。请指导我。

回答by Vlad Mihalcea

Using 1000 database connections doesn't sound like a very good idea. Each extra database connection requires extra RAM and increases the likelihood of concurrency issues (deadlocks).

使用 1000 个数据库连接听起来不是一个好主意。每个额外的数据库连接都需要额外的 RAM,并增加并发问题(死锁)的可能性。

Since you use C3P0 you should have a max connection size:

由于您使用 C3P0,您应该有一个最大连接大小:

<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">20</property>

If you run out of connections then it may be because:

如果连接用完,则可能是因为:

  • you don't close the Hibernate Session, and the associated JDBC connection doesn't get released to the pool
  • your queries take too long to execute and so they don't release connections fast enough
  • 您没有关闭 Hibernate Session,并且关联的 JDBC 连接不会被释放到池中
  • 您的查询执行时间太长,因此它们释放连接的速度不够快

I recommend using a connection pool size utility, such as FlexyPoolto understand better the database connection usage patterns.

我建议使用连接池大小实用程序,例如FlexyPool以更好地了解数据库连接使用模式。

Regarding the two choices:

关于两个选择:

  • The 1st example contradicts the automatic session management support offered by Spring. When you use Spring you should not manage Hibernate Sessions yourself. You should let the transaction manager call the appropriate Hibernate initializing callbacks on a new transaction boundary.

    In your example, if the session throws an exception, the session will not be closed and the connection might be dangling around. That's because you haven't used a try/finally block for releasing the Session.

  • The 2nd example is better, but you need to wrap it into a @Transactionalservice.

  • 第一个示例与 Spring 提供的自动会话管理支持相矛盾。当您使用 Spring 时,您不应该自己管理 Hibernate Sessions。您应该让事务管理器在新的事务边界上调用适当的 Hibernate 初始化回调。

    在您的示例中,如果会话抛出异常,会话将不会关闭并且连接可能会悬空。那是因为您没有使用 try/finally 块来释放会话。

  • 第二个例子更好,但你需要把它包装成一个@Transactional服务。