我有一个长期运行的方法,它通过EntityManager(TopLink Essentials)执行大量本机SQL查询。每个查询只需要几毫秒就可以运行,但是有成千上万的查询。这发生在单个EJB事务中。15分钟后,数据库关闭连接,导致以下错误:
Exception [TOPLINK-4002] (Oracle TopLink Essentials - 2.1 (Build b02-p04 (04/12/2010))): oracle.toplink.essentials.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: Closed Connection
Error Code: 17008
Call: select ...
Query: DataReadQuery()
at oracle.toplink.essentials.exceptions.DatabaseException.sqlException(DatabaseException.java:319)
.
.
.
RAR5031:System Exception.
javax.resource.ResourceException: This Managed Connection is not valid as the phyiscal connection is not usable
at com.sun.gjc.spi.ManagedConnection.checkIfValid(ManagedConnection.java:612)
在JDBC连接池中,我设置了is-connection-validation-required="true"
和connection-validation-method="table"
,但这并没有帮助。
我假设JDBC连接验证正是为了处理这种错误。我还查看了TopLink扩展(http://www.oracle.com/technetwork/middleware/ias/toplink-jpa-extensions-094393.html)进行某种超时设置,但一无所获。还有TopLink会话配置文件(http://download.oracle.com/docs/cd/B14099_19/web.1012/b15901/sessions003.htm)但我认为那里也没有什么有用的。
我没有访问OracleDBA表的权限,但我认为Oracle会在15分钟后根据CONNECT_TIME配置文件变量中的设置关闭连接。
有没有其他方法可以使TopLink或JDBC池重新建立封闭的连接?
数据库为Oracle 10g,应用服务器为Sun Glassfish 2.1.1。
所有JPA实现(在Java EE容器上运行)都使用带有关联连接池的数据源来管理与数据库的连接。
持久性上下文本身通过persistence.xml
中的适当条目与数据源相关联。如果要更改客户端上的连接超时设置,则必须重新配置关联的连接池。
在Glassfish中,可以通过编辑池设置来重新配置与连接池相关的超时设置,如下链接所示:
- 更改GlassFish 3.1中的超时设置
- 更改GlassFish 2.1中的超时设置
在服务器端(如果其设置低于客户端设置,则会更重要),可以将Oracle数据库配置为具有与用户帐户关联的数据库配置文件。配置文件的会话idle_time和connect_time参数将构成客户端-服务器交互的这一方面中重要的超时设置。如果没有设置配置文件,那么默认情况下,超时是不受限制的。
除非您有某种RAC故障切换,否则当连接终止时,它将结束会话和事务。
管理员可能设置了一些限制,以防止失控的事务或单个作业"占用"池中的连接。您通常不希望在池中长时间锁定连接。
如果这些查询不一定是同一事务的一部分,那么您可以尝试终止并重新启动新的连接。
你是否能够重组你的代码,使其在15分钟内完成。后台的存储过程可能比在网络上拖动数千个操作的结果更快地完成这项工作。
我看到您设置了connection-validation-method="table"
和is-connection-validation-required="true"
,但您没有提到您指定了要验证的表;您是否设置了validation-table-name="any_table_you_know_exists"
并提供了任何现有的表名?validation-table-name="existing_table_name"
是必需的。
有关连接验证的更多详细信息,请参阅本文。
相关的StackOverflow文章也有类似的问题——他想清空整个无效的连接池。