Glassfish,PostgreSQL和封闭式连接

时间:2012-06-20 08:25:41

标签: java postgresql glassfish database-connection connection-pooling

我们在Glassfish上使用MySQL使用JPA(Hibernate),它运行正常。

然后我们切换到PostgreSQL,几乎一切都运行良好。我们遇到的唯一问题是,一段时间后,应用程序停止响应并抛出异常,因为与DB的连接已关闭:

[#|2012-06-19T21:51:22.050+0200|SEVERE|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=38;_ThreadName=Thread-2;|4816089 [p: thread-pool-1; w: 21] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 0, SQLState: 08006
[#|2012-06-19T21:51:22.050+0200|SEVERE|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=38;_ThreadName=Thread-2;|4816089 [p: thread-pool-1; w: 21] ERROR org.hibernate.util.JDBCExceptionReporter - An I/O error occured while sending to the backend.
[#|2012-06-19T21:51:22.052+0200|SEVERE|glassfish3.1.2|javax.enterprise.resource.resourceadapter.com.sun.enterprise.resource|_ThreadID=38;_ThreadName=Thread-2;|RAR5031:System Exception
javax.resource.spi.LocalTransactionException: This connection has been closed.
        at com.sun.gjc.spi.LocalTransactionImpl.rollback(LocalTransactionImpl.java:134)
        at com.sun.enterprise.resource.ConnectorXAResource.rollback(ConnectorXAResource.java:213)
        at com.sun.enterprise.transaction.JavaEETransactionImpl.rollback(JavaEETransactionImpl.java:571)
        at com.sun.enterprise.transaction.JavaEETransactionManagerSimplified.rollback(JavaEETransactionManagerSimplified.java:893)
        at com.sun.enterprise.transaction.UserTransactionImpl.rollback(UserTransactionImpl.java:234)
        at ch.ethz.id.wai.lakshmi.engine.common.TransactionHelper.rollbackTransaction(TransactionHelper.java:43)
        at ch.ethz.id.wai.lakshmi.stdcmp.tracking.StandardTracking.updateStatus(StandardTracking.java:50)
        at ch.ethz.id.wai.lakshmi.engine.ejb.LakshmiServerBean.updateTrackingStatus(LakshmiServerBean.java:992)
        at ch.ethz.id.wai.lakshmi.engine.ejb.LakshmiServerBean.executeNextWorkflowStep(LakshmiServerBean.java:771)
        at ch.ethz.id.wai.lakshmi.engine.ejb.LakshmiServerBean.executeNextWorkflowStep(LakshmiServerBean.java:683)
        at ch.ethz.id.wai.lakshmi.engine.ejb.LakshmiServerBean.continueWorkflow(LakshmiServerBean.java:602)
        at ch.ethz.id.wai.lakshmi.engine.ejb.LakshmiServerBean.processSubmitOrderRequest(LakshmiServerBean.java:487)
        at ch.ethz.id.wai.lakshmi.engine.ejb.LakshmiServerBean.onMessage(LakshmiServerBean.java:360)
        at sun.reflect.GeneratedMethodAccessor133.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1052)
        at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1124)
        at com.sun.ejb.containers.BaseContainer.invokeTargetBeanMethod(BaseContainer.java:4180)
        at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:5368)
        at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:5348)
        at com.sun.ejb.containers.MessageBeanContainer.deliverMessage(MessageBeanContainer.java:1099)
        at com.sun.ejb.containers.MessageBeanListenerImpl.deliverMessage(MessageBeanListenerImpl.java:81)
        at com.sun.enterprise.connectors.inbound.MessageEndpointInvocationHandler.invoke(MessageEndpointInvocationHandler.java:171)
        at $Proxy264.onMessage(Unknown Source)
        at com.sun.messaging.jms.ra.OnMessageRunner.run(OnMessageRunner.java:260)
        at com.sun.enterprise.connectors.work.OneWork.doWork(OneWork.java:114)
        at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.performWork(ThreadPoolImpl.java:497)
        at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:540)
Caused by: org.postgresql.util.PSQLException: This connection has been closed.
        at org.postgresql.jdbc2.AbstractJdbc2Connection.checkClosed(AbstractJdbc2Connection.java:714)
        at org.postgresql.jdbc2.AbstractJdbc2Connection.rollback(AbstractJdbc2Connection.java:731)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.postgresql.ds.jdbc23.AbstractJdbc23PooledConnection$ConnectionHandler.invoke(AbstractJdbc23PooledConnection.java:352)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.postgresql.ds.jdbc23.AbstractJdbc23PooledConnection$ConnectionHandler.invoke(AbstractJdbc23PooledConnection.java:352)
        at $Proxy161.rollback(Unknown Source)
        at com.sun.gjc.spi.LocalTransactionImpl.rollback(LocalTransactionImpl.java:128)
        ... 28 more

我们以相同的方式为MySQL和PostgreSQL创建连接池:

asadmin create-jdbc-connection-pool \
    --restype javax.sql.DataSource \
    --datasourceclassname org.postgresql.jdbc2.optional.PoolingDataSource \
    --property URL='jdbc:postgresql://127.0.0.1:5432/doi':serverName=localhost:databaseName=doi:user=doi:password=******** doi

asadmin create-jdbc-connection-pool \
    --restype javax.sql.DataSource \
    --datasourceclassname com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource \
    --property serverName=127.0.0.1:dataBaseName=doi:user=doi:********=doi:schema=doi doi

如何配置数据池以关闭空闲连接或使其保持活动状态并避免关闭连接错误?

1 个答案:

答案 0 :(得分:2)

只要符合以下条件,Pg连接应无限期保持有效:

  • 数据库服务器未停止或重新启动
  • 数据库服务器的IP不会更改
  • 客户端和服务器之间没有连接跟踪或NAT路由器

后两个不是问题,因为你连接到localhost,所以你不需要任何特殊措施来保持你的连接活着。

我有点怀疑你正在使用org.postgresql.ds.PGSimpleDataSource。 Glassfish有自己的池,您可能应该使用该计划org.postgresql.datasource.Datasource。你很可能有两层游泳池,结果可能令人困惑。您将在the PgJDBC documentation中注明:

  

此处提供的池化数据源实现并不是最多的   功能丰富的世界。除此之外,连接永远不会   关闭,直到游泳池关闭;没有办法缩小   池。同样,为默认用户以外的用户请求连接   配置的用户不是池。它的错误处理有时不能   从池中删除断开的连接。一般情况下不是   建议使用PostgreSQL™提供的连接池。校验   您的应用程序服务器或查看优秀的jakarta commons   DBCP项目。

请切换为使用org.postgresql.ds.PGSimpleDataSource,看看是否能解决您的问题。