gpt4 book ai didi

java - 连接未关闭

转载 作者:行者123 更新时间:2023-12-02 08:40:40 24 4
gpt4 key购买 nike

我正在使用 Java 8 运行 SpringBoot 2.0 webService。我必须使用PreparedStatement 来处理 clob,因此我必须创建自己的连接,而不是让 Spring 创建 Oracle 连接。然而现在我似乎出现了连接泄漏,即使我在完成后关闭了连接,并且在我运行 webService 3 次后(每次运行泄漏 3 个连接),我收到错误:

 org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30002ms.
DEBUG - HikariPool-1 - Pool stats (total=10, active=9, idle=1, waiting=0)

因此我在 application.properties 中添加了以下内容来定位泄漏:

spring.datasource.hikari.leakDetectionThreshold=2000

然后我在第一次运行 webService 时收到以下错误:

java.lang.Exception: Apparent connection leak detected
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:128)
at com.clarivate.singularity.chemworkbench.dcrws.database.ReadFromDb.readStructureSearch(ReadFromDb.java:187)

报错的方法如下:

public class myClass(){
@Autowired
NamedParameterJdbcTemplate jdbcTemplate;

@Transactional
public List<DcrData> readStructureSearch(String sqlStr, String fileData) throws SQLException {
List<DcrData> dcrDataList = null;
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = this.jdbcTemplate.getJdbcTemplate().getDataSource().getConnection().unwrap(OracleConnection.class); // <<<< This is line 187 mentioned above which is giving the error
Clob myClob = conn.createClob();

int ret = myClob.setString( 1, fileData);

ps = conn.prepareStatement(sqlStr);
ps.setClob(1,myClob); // This works, Types.CLOB doesn't work.

rs = ps.executeQuery();

ResultSetHandler<List<DcrData>> handler =
new BeanListHandler<DcrData>(DcrData.class, new BasicRowProcessor(new GenerousBeanProcessor()));

dcrDataList = handler.handle(rs);
return dcrDataList;
}finally {
if (rs != null) {
rs.close();
}
if (ps != null) {
ps.close();
}
if (conn != null) {
conn.close();
}
logger.info("DSxxx4");
}
}

如何创建一个不泄漏的连接,为什么 Hikari 认为我的 conn.close() 方法没有关闭连接?任何想法表示赞赏。

最佳答案

我对这个函数正在做什么有点困惑。它似乎在 CLOB 上运行选择约束,但我可能是错的。我在不知情的情况下重现该问题时遇到了麻烦。

也就是说,这里有一些可以尝试的事情。首先,您不需要 NamedParameterJdbcTemplate,只需要一个 DataSource。尝试 Autowiring 。其次,似乎没有理由获取原始 Oracle 连接本身,您可以直接使用数据源返回的连接。第三,try with resources模式使代码更容易遵循Java将自动处理关闭资源。它在 Java 8 中可用。最后,释​​放 CLOB 或许会有所帮助。

这是一个包含我提到的内容的示例:

public class MyClass {

@Autowired
DataSource dataSource;

@Transactional
public List<DcrData> readStructureSearch(String sqlStr, String fileData) throws SQLException {

try (Connection conn = this.dataSource.getConnection()) {
Clob myClob = conn.createClob();

myClob.setString(1, fileData);

try (PreparedStatement ps = conn.prepareStatement(sqlStr)) {
ps.setClob(1, myClob);

try (ResultSet rs = ps.executeQuery()) {
ResultSetHandler<List<DcrData>> handler =
new BeanListHandler<>(DcrData.class, new BasicRowProcessor(new GenerousBeanProcessor()));

List<DcrData> dcrDataList = handler.handle(rs);

myClob.free();

return dcrDataList;
}
}
}
}
}

关于java - 连接未关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61408298/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com