java.sql.SQLRecoverableException - 从 jdbc 重新连接

标签 java spring oracle jdbc oracle-sqldeveloper

在使用 Apache JDBC 连接来连接到数据库的应用程序中,我偶尔会收到“java.sql.SQLRecoverableException”。经过查找根本原因,我了解到这可能是由于oracle服务器端连接终止造成的。我使用的是oracle 11G版本。

现在我的要求是在执行任何查询之前我必须确保连接仍然有效并且没有终止。如果连接从 oracle 端终止,我需要建立一个新连接。

我不确定如何实现这一点或测试它。我尝试从下面的查询中获取 session :

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" />

最佳答案

连接似乎被某些防火墙或其他 Activity 断开。 我们遇到过类似的问题,数据库终止空闲 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 的单位是毫秒。

以上配置将检查无效连接,如果数据库或防火墙突然关闭它们,则将其从池中删除。

关于java.sql.SQLRecoverableException - 从 jdbc 重新连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56111248/

相关文章:

java - 在 Java 中比较整数

Java8 : How volatile field work with lambda

c# - 连接到 Oracle 数据库时出现 OracleException (0x80004005)

java - 如何在 UI 上显示表格中的 100 万条数据

java - 创建的 Runnables 的 lambda 的不同行为

java - 简单回归 - 截距和斜率计算错误

java - 基本 AOP 程序抛出 BeanCurrentlyInCreationException

java - bean 名称 ' ' 的 BindingResult 和普通目标对象都不能用作请求属性

java - 事务注释在 Spring Boot 中不起作用

java - 这是什么意思? (java,数据库)