在Hibernate/Spring事务中优雅地处理过时的数据库连接 [英] elegantly handling stale database connections in Hibernate/Spring Transactions
问题描述
我有一个可以在测试中正常运行的系统,但是现在我已经将它们移至生产服务器,并准备扔掉交换机,这是有问题的.
i have a system that has been working fine in testing but now that i have moved them to the production servers and am ready to throw the switch, im having a problem.
如果应用程序闲置大约15分钟,则spring事务服务中的数据库连接将断开.发生这种情况后,第一个来到该应用程序的人会受到欢迎
if the application sits idle for around 15 minutes, the DB connection in the spring transaction service drops. the first person that comes to the app after that happens is greeted with this
org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is org.hibernate.exception.JDBCConnectionException: Cannot open connection
org.springframework.orm.hibernate3.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:596)
org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:371)
org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:335)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:105)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:621)
parity.persistence.DataAccess$$EnhancerByCGLIB$$921ef13.find(<generated>)
parity.model.Configuration.getConfiguration(Configuration.java:84)
parity.model.Configuration.getSetting(Configuration.java:46)
parity.model.Configuration$$FastClassByCGLIB$$8355c3d0.invoke(<generated>)
net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:617)
parity.model.Configuration$$EnhancerByCGLIB$$5e96e8b9.getSetting(<generated>)
parity.model.OnlineStatus.getSiteStatus(OnlineStatus.java:50)
parity.action.site.SiteStatusInterceptor.intercept(SiteStatusInterceptor.java:16)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:52)
org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:498)
org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:434)
root cause
如果您在浏览器中点击F5,它将重新连接并正常运行.看起来像spring在按照第一个请求进行操作时,请继续前进,我死了,在死亡过程中,重新连接到数据库.但我不确定.
if you hit F5 on your browser, it reconnects and runs just fine. it looks like spring is doing something along the lines of the first request, going eek, i died, and in the process of dieing, reconnecting to the database. but im not sure.
我一直在寻找解决此问题的方法,但除非我使用c3p0或weblogic,否则每个人都不了解.有没有办法来解决这个问题?这是我的配置文件
i have been searching for ways to solve this but it looks like unless i am using c3p0 or weblogic everyone is clueless. is there a way to fix this? here are my config files
hibernate.cfg.xml:
hibernate.cfg.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
<property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
<property name="connection.autocommit">false</property>
<property name="show_sql">false</property>
<property name="use_sql_comments">false</property>
</session-factory>
</hibernate-configuration>
transaction-service.xml:
transaction-service.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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="boardingSessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocations">
<list>
<value>classpath:hibernate/boarding-hibernate.cfg.xml</value>
<value>classpath:boarding-hibernate.cfg.xml</value>
</list>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
</bean>
<bean id="boardingTransactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="boardingSessionFactory" />
<qualifier value="boarding" />
</bean>
<tx:advice id="boardingTxAdvice" transaction-manager="boardingTransactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true" />
<tx:method name="*" />
</tx:attributes>
</tx:advice>
</beans>
请注意,我的休眠状态使用了2个文件,其中一个在API中用于处理全局设置,另一个在应用程序本身中具有特定于应用程序的设置.就此而言,我认为,全球性才是最重要的.
note, my hibernate uses 2 files, one in the API that handles global settings, and one in the app itself that has application specific settings. for purposes here, the global one is all that matters, i think.