【问题标题】:How to handle max database connections with Hibernate?如何使用 Hibernate 处理最大数据库连接?
【发布时间】:2015-03-09 22:57:42
【问题描述】:

下面是来自 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>

下面是 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;
}

以及项目中的其他代码(代码 2)

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

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

【问题讨论】:

    标签: java mysql spring hibernate c3p0


    【解决方案1】:

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

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

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

    如果你的连接用完了,那可能是因为:

    • 您没有关闭 Hibernate Session,并且关联的 JDBC 连接不会释放到池中
    • 您的查询执行时间过长,因此它们释放连接的速度不够快

    我建议使用connection pool size utility,例如FlexyPool,以更好地了解数据库连接使用模式。

    关于两种选择:

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

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

    • 第二个示例更好,但您需要将其包装到 @Transactional 服务中。

    【讨论】:

    • 你能告诉我,是因为代码 1 还是代码 2。?如果我不关闭代码 1 的连接,那么它会每次都创建新连接吗?还是会使用现有打开的?
    • 是真的。出于好奇,我想知道,在代码1中,我正在打开连接并正确关闭它,那么为什么它会增加连接数。?为什么连接没有通过调用 close() 立即关闭。?连接在某个特定时间后关闭,但直到那时它达到最大连接。
    • 你怎么知道你有超过 1000 个连接?大多数数据库只允许几百只。
    • cloud.google.com/sql/pricing。我已采取 D8 层计费计划。从谷歌开发者控制台--->存储--->云sql---->活动连接。在该页面上,它显示了活动连接数的图表
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-30
    • 2012-03-02
    • 1970-01-01
    • 2010-12-12
    • 2010-09-13
    相关资源
    最近更新 更多