在Hibernate/Spring事务中优雅地处理过时的数据库连接 [英] elegantly handling stale database connections in Hibernate/Spring Transactions

查看:48
本文介绍了在Hibernate/Spring事务中优雅地处理过时的数据库连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个可以在测试中正常运行的系统,但是现在我已经将它们移至生产服务器,并准备扔掉交换机,这是有问题的.

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.

推荐答案

Hibernate自己的连接池算法相当 基本的.它旨在帮助您入门,而不是 用于生产系统,甚至用于性能 测试.您应该使用第三方池以获得最佳性能,并且 稳定性.

Hibernate's own connection pooling algorithm is, however, quite rudimentary. It is intended to help you get started and is not intended for use in a production system, or even for performance testing. You should use a third party pool for best performance and stability.

因此,答案很简单:使用真实的连接池,并将其配置为在将连接提供给应用程序之前测试连接.

So, the answer is simple: use a real connection pool, and configure it to test connections before giving them to the application.

这篇关于在Hibernate/Spring事务中优雅地处理过时的数据库连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆