簡體   English   中英

Spring 3 MVC Hibernate 3.5.4 hibernateTemplate沒有關閉連接(非事務性)

[英]Spring 3 MVC Hibernate 3.5.4 hibernateTemplate not closing connections (non-transactional)

我們在沒有事務的情況下使用Spring MVC 3.0.5.RELEASE和Hibernate 3.5.4-Final。 每次我們通過hibernateTemplate訪問數據庫時,它都會創建一個新連接,並且似乎永遠不會關閉它們。

更新:我們將maxActive和maxIdle設置為5.應用程序在嘗試打開第6個連接時將掛起。 我們允許100個mysql連接。

我們的hibernateTemplate是Autowired,因此我們不直接管理這些連接。 有關如何確保這些連接關閉的任何想法?

這是我們用於休眠的彈簧配置:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName">
        <value>${jdbc.driverClassName}</value>
    </property>
    <property name="url">
        <value>${jdbc.url}</value>
    </property>
    <property name="username">
        <value>${jdbc.username}</value>
    </property>
    <property name="password">
        <value>${jdbc.password}</value>
    </property>
    <property name="maxActive">
        <value>5</value>
    </property>
    <property name="maxIdle">
        <value>5</value>
    </property>
    <property name="removeAbandoned">
        <value>true</value>
    </property>
    <property name="removeAbandonedTimeout">
        <value>30</value>
    </property>
</bean>

<alias name="dataSource" alias="userInfoDataSource"/>

<!-- Hibernate SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource">
        <ref local="dataSource"/>
    </property>
    <property name="packagesToScan" value="com.domain"/>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.connection.release_mode">after_statement</prop>
            <prop key="hibernate.transaction.flush_before_completion">true</prop>                
        </props>
    </property>
</bean>

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

這是我們的HibernateRepository實現:

package com.dataAccess.impl;

import org.hibernate.criterion.DetachedCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public abstract class HibernateRepositoryImpl<T> implements com.dataAccess.Repository<T> {

  @Autowired
  protected HibernateTemplate hibernateTemplate;

  public List<T> find(String query) {
    return hibernateTemplate.find(query);
  }

  @Override
  public void saveOrUpdate(T ENTITY) {
    hibernateTemplate.saveOrUpdate(ENTITY);
  }

  @Override
  public List<T> find(DetachedCriteria criteria) {
    return hibernateTemplate.findByCriteria(criteria);
  }

  @Override
  public void delete(T ENTITY) {
    hibernateTemplate.delete(ENTITY);
  }
}

這是我們正在使用它的一個例子,它似乎泄漏連接:

package com.dataAccess.impl;

import com.domain.Trigger;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public class TriggerRepository extends HibernateRepositoryImpl<Trigger> {
  public List<Trigger> getActiveTriggers(Integer patientId) {
    DetachedCriteria findActiveTriggers = DetachedCriteria.forClass(Trigger.class).add(
        Restrictions.and(
            Restrictions.eq("patientId", patientId),
            Restrictions.eq("active", true)
        )
    );
    return super.find(findActiveTriggers);
  }
  public List<Trigger> getInActiveTriggers(Integer patientId) {
    DetachedCriteria findActiveTriggers = DetachedCriteria.forClass(Trigger.class).add(
        Restrictions.and(
            Restrictions.eq("patientId", patientId),
            Restrictions.eq("active", false)
        )
    );
    return super.find(findActiveTriggers);
  }

  public Trigger get(Integer triggerId) {
    return hibernateTemplate.get(Trigger.class, triggerId);
  }
}

問題最終是一些遺留代碼被稱為將多個方法鏈接在一起,其中創建連接的方法 - 所以連接永遠不會被分配(很難發現),也不會被關閉。 這段代碼是間接加載的,我錯誤地懷疑我的Hibernate / Spring配置有問題。

如果遇到類似問題,請注意以下代碼行:

connectionManager.getConnection().prepareStatement(..).<whatever>

getConnection()調用可能會打開一個新連接,並且每個准備好的語句都有一個更改才能關閉。

我相信如果您沒有使用transactionManager,那么您應該在HibernateRepositoryImpl類中的每個操作之后關閉Hibernate會話。

你在大多數情況下可能會被認為是一個錯誤 - 你正在打開新的Hibernate會話,但它們永遠不會被關閉 - 你看到實際對數據庫執行的SQL語句的唯一原因是因為你有hibernate.transaction.flush_before_completion屬性設置為true。

另外請確保您沒有創建多個HibernateTemplate實例,i

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("META-INF/spring/applicationContext.xml");
Object o=context.getBean("hibernateTemplate");

對象o必須在某處緩存,並在您的應用程序代碼要求hibernatetemplate實例時返回。

謝謝

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM