我有一个移动应用程序,它连接到用Spring Hibernate编写的Azure Web服务,该服务与Azure SQL服务器通信以执行数据操作。 在hibernate中,我们没有配置任何连接管理器。我们使用Hibernate sessionFactory来管理连接。 最近,在使用该应用程序的用户太多之后,我们发现Azure在达到1920 TCP连接的最大连接限制后自动重新启动服务。 一旦使用TCP连接,则进入CLOSE_WAIT状态或TIME_WAIT状态。 他们没有正确关闭连接。 这与某些Azure VM Server没有关闭连接或与使用的Java编码样式有关。
的pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mastek</groupId>
<artifactId>transaction-rs</artifactId>
<version>1.0</version>
<packaging>war</packaging>
<name>transaction-rs</name>
<properties>
<springframework.version>4.0.6.RELEASE</springframework.version>
<hibernate.version>4.3.6.Final</hibernate.version>
<sqlserver.version>4.0</sqlserver.version>
<swagger-version>1.3.0</swagger-version>
</properties>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
<!-- Hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<!-- MS SQL server driver -->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc4</artifactId>
<version>${sqlserver.version}</version>
</dependency>
<!-- orika mapper -->
<dependency>
<groupId>ma.glasnost.orika</groupId>
<artifactId>orika-core</artifactId>
<version>1.4.6</version>
</dependency>
<!-- resteasy api -->
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>3.0.13.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxb-provider</artifactId>
<version>3.0.13.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>3.0.13.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson-provider</artifactId>
<version>3.0.13.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-spring</artifactId>
<version>3.0.13.Final</version>
</dependency>
<!-- Resteasy Servlet Container Initializer -->
<!-- scope 'provided' for JBoss AS -->
<!-- <dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-servlet-initializer</artifactId>
<version>3.0.11.Final</version>
<scope>compile</scope>
</dependency> -->
<!-- slf4j and logger -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.1</version>
</dependency>
<!-- swagger for documentation -->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-jaxrs</artifactId>
<version>1.5.0</version>
</dependency>
<!-- junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>3.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
<!-- commons -->
<dependency>
<groupId>com.mastek.commons</groupId>
<artifactId>commons</artifactId>
<version>1.0</version>
</dependency>
<!-- JSON to XML -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20160212</version>
</dependency>
<!-- Gson: Java to Json conversion -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.2.2</version>
<scope>compile</scope>
</dependency>
<!-- swagger start -->
<dependency>
<groupId>com.wordnik</groupId>
<artifactId>swagger-jaxrs_2.9.1</artifactId>
<version>${swagger-version}</version>
</dependency>
<dependency>
<groupId>com.wordnik</groupId>
<artifactId>swagger-annotations_2.9.1</artifactId>
<version>${swagger-version}</version>
</dependency>
<!-- swagger end -->
</dependencies>
<build>
<finalName>transaction-rs</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
持久性-config.xml中:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<context:property-placeholder ignore-resource-not-found="true" location="file:/sdt/configuration/services.properties, file:../../sdt/configuration/services.properties, classpath:application.properties" />
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${transaction.service.jdbc.driverClassName}" />
<property name="url" value="${transaction.service.jdbc.url}"/>
<property name="username" value="${transaction.service.jdbc.username}" />
<property name="password" value="${transaction.service.jdbc.password}"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" >
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan">
<list>
<value>com.mastek.commons.data.entity</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="persistenceExceptionTranslationPostProcessor"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
</beans>
这是我的DAOImpl.java的一部分:
package com.mastek.security.data.service;
import static com.mastek.commons.util.ApplicationConstants.DELIMITER;
import static com.mastek.commons.util.ApplicationConstants.END;
import static com.mastek.commons.util.ApplicationConstants.GET_WEEK;
import static com.mastek.commons.util.ApplicationConstants.REGISTER_USER;
import static com.mastek.commons.util.ApplicationConstants.START;
import static com.mastek.commons.util.ApplicationConstants.USER_ID;
import static com.mastek.commons.util.ApplicationConstants.VEFIFY_USER;
import static com.mastek.commons.util.ApplicationConstants.GET_USER_BY_EMAIL;
import java.util.Date;
import org.hibernate.Query;
import org.hibernate.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.mastek.commons.data.dao.impl.AbstractDAO;
import com.mastek.commons.data.entity.VWLoginUser;
import com.mastek.commons.data.entity.VWUser;
import com.mastek.commons.data.entity.VWWeekEnding;
import com.mastek.commons.domain.UserDO;
import com.mastek.commons.domain.WeekDO;
import com.mastek.commons.exception.DataStoreException;
import com.mastek.commons.exception.SystemException;
import com.mastek.commons.util.CommonUtil;
import ma.glasnost.orika.MapperFacade;
/**
* The Class RegistrationDAOImpl.
*/
@Repository
public class RegistrationDAOImpl extends AbstractDAO implements RegistrationDAO
{
/** The Constant logger. */
private static final Logger logger = LoggerFactory.getLogger(RegistrationDAOImpl.class);
/** The mapper facade. */
@Autowired
private MapperFacade mapperFacade;
/**
* This method verifies logged in user.
*
* @param surname the surname
* @param userId the user id
* @return the user do
* @throws DataStoreException the data store exception
*/
@Override
public UserDO verifyUser(String surname, long userId) throws DataStoreException
{
logger.info(VEFIFY_USER + DELIMITER + USER_ID + userId + DELIMITER + START);
UserDO userDO = null;
Session session = openSession();
try
{
Query query = session.getNamedQuery("VWLoginUser.getUser");
query.setLong("userId", userId);
query.setString("surname", surname);
VWLoginUser user = (VWLoginUser) query.uniqueResult();
userDO = mapperFacade.map(user, UserDO.class);
}
catch (org.hibernate.exception.DataException de)
{
logger.error(VEFIFY_USER + DELIMITER + USER_ID + userId + DELIMITER + SystemException.Type.DE.getErrorCode() + DELIMITER + SystemException.Type.DE.getMessage());
logger.error(VEFIFY_USER, de);
throw new DataStoreException(new SystemException(SystemException.Type.DE, de));
}
catch (org.hibernate.exception.JDBCConnectionException jdbcce)
{
logger.error(VEFIFY_USER + DELIMITER + USER_ID + userId + DELIMITER + SystemException.Type.JDBCCE.getErrorCode() + DELIMITER + SystemException.Type.JDBCCE.getMessage());
logger.error(VEFIFY_USER, jdbcce);
throw new DataStoreException(new SystemException(SystemException.Type.JDBCCE, jdbcce));
}
catch (org.hibernate.exception.SQLGrammarException sqlge)
{
logger.error(VEFIFY_USER + DELIMITER + USER_ID + userId + DELIMITER + SystemException.Type.SQLGE.getErrorCode() + DELIMITER + SystemException.Type.SQLGE.getMessage());
logger.error(VEFIFY_USER, sqlge);
throw new DataStoreException(new SystemException(SystemException.Type.SQLGE, sqlge));
}
finally
{
session.clear();
session.close();
}
logger.info(VEFIFY_USER + DELIMITER + USER_ID + userId + DELIMITER + END);
return userDO;
}
}
这是我的AbstractDAO.java:
package com.mastek.commons.data.dao.impl;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
/**
* The Class AbstractDAO.
*/
public abstract class AbstractDAO
{
/** The session factory. */
@Autowired
private SessionFactory sessionFactory;
/**
* Gets the session.
*
* @return the session
*/
protected Session getSession()
{
return sessionFactory.getCurrentSession();
}
/**
* Open session.
*
* @return the session
*/
protected Session openSession()
{
Session session = sessionFactory.openSession();
return session;
}
/**
* Persist.
*
* @param entity the entity
*/
public void persist(Object entity)
{
getSession().persist(entity);
}
/**
* Delete.
*
* @param entity the entity
*/
public void delete(Object entity)
{
getSession().delete(entity);
}
/**
* Gets the session factory.
*
* @return the session factory
*/
public SessionFactory getSessionFactory()
{
return sessionFactory;
}
/**
* Sets the session factory.
*
* @param sessionFactory the session factory
*/
public void setSessionFactory(SessionFactory sessionFactory)
{
this.sessionFactory = sessionFactory;
}
}