java - java.sql.SQLRecoverableException - 从 jdbc 重新连接
问题描述
在我使用 Apache JDBC 连接连接到数据库的应用程序中,我偶尔会收到“java.sql.SQLRecoverableException”。在搜索了根本原因后,我了解到它可能是由于与 oracle 服务器端的连接终止造成的。我使用的是 oracle 11G 版本。
现在我的要求是我必须确保连接仍然有效并且在执行任何查询之前没有终止。如果连接从 oracle 端终止,我需要建立一个新连接。
我不确定如何实现或测试它。我尝试从以下查询中获取会话:
select * from v$session where username is not null;
当我打开 SQL Developer 并且应用程序(使用相同用户凭据的 2 个应用程序)也打开时,它会显示一个结果。我想知道如何终止与 SQL 的连接并重现“SQLRecoverableException”以进行测试,并在问题发生后重新连接到数据库。
由于我是数据库连接的新手,因此我不确定要做什么或要研究什么才能实现这一目标。请帮我解决这个问题。
我在 spring-servlet.xml 中的 JDBC 连接如下所示:
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${myjdbc.driverClassName}" />
<property name="url" value="${myjdbc.url}" />
<property name="username" value="${myjdbc.username}" />
<property name="password" value="${myjdbc.password}" />
</bean>
<context:property-placeholder location="classpath:myjdbc.properties" />
解决方案
似乎某些防火墙或其他活动正在断开连接。我们遇到了类似的问题,即数据库终止了空闲 30 分钟的连接。
为了克服这个问题,我们通过指定以下属性调整了数据库池
testOnBorrow:-Setting it true will force the pooling provider to run the validation query while handing out the connection to the application.
testWhileIdle:-Setting it true will enable the validation when the connection is sitting idle in the pool.
timeBetweenEvictionRunsMillis:- Setting this property to non-zero will allow the evictor thread to run,which will test the idle connections.
重现该问题将需要终止数据库端的连接。我们使用 mssql 执行了一个小测试,其中我们可以使用服务器工具终止连接,并且池再次建立连接。
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${myjdbc.driverClassName}" />
<property name="url" value="${myjdbc.url}" />
<property name="username" value="${myjdbc.username}" />
<property name="password" value="${myjdbc.password}" />
<property name="testOnBorrow" value="true" />
<property name="testWhileIdle" value="true" />
<property name="timeBetweenEvictionRunsMillis" value="3000" />
</bean>
请注意 timeBetweenEvictionRunsMillis 以毫秒为单位。
上述配置将检查无效连接,如果它们被数据库或防火墙突然关闭,则将其从池中删除。
推荐阅读
- ios - 如何检测 iOS 中可能的音频输出?
- neo4j - Cypher (Neo4j) - 只要来自节点的一个关系满足条件而不管搜索路径如何,都可以找到所有关系?
- android - Android Kotlin - 如何在 Activity 中读取 NFC 标签
- sql - 如何通过读取 medata 创建可重用的 vertica sql
- python - 第 4.3 节练习 #5 - Allen Downey 的“Think Python”
- android - 状态管理的静态变量
- html - AngularJS 文本框和日历图标需要并排出现
- windows - 在授予用户完全控制权的同时需要帮助删除拒绝权限
- postgresql - psql 会话的 Postgres 表别名
- node.js - 如何让发布请求显示在控制台中