欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring JdbcTemplate释放连接

程序员文章站 2022-06-13 23:12:10
...

前言

Spring JdbcTemplate在通过DataSourceUtils管理Connection,DataSourceUtils通过ConnectionHolder管理Connection。并且将ConnectionHolder保存在ThreadLocal,所以是线程安全的。

详见org.springframework.jdbc.datasource.DataSourceUtils#getConnection

 

问题

但是在释放的时候,ConnectionHolder的实现类SimpleConnectionHandle的releaseConnection缺失一个空方法。导致该Connection出现问题后无法更换Connection。比如,使用数据库连接池,重启数据库后SQL会一直执行失败。

 

解决方法

org.springframework.jdbc.datasource.DataSourceUtils#doGetConnection方法中通过TransactionSynchronizationManager.getResource(dataSource);返回ConnectionHolder,如果返回null则重新创建,debug下去,发现在org.springframework.transaction.support.TransactionSynchronizationManager#doGetResource方法里面,通过((ResourceHolder) value).isVoid()判断是否值为空,如果isVoid返回true,则删除当前线程中的ConnectionHolder。所以想办法将isVoid设置为true,就可以实现释放当前Connection。

Exception中处理代码如下:

 

public static void released(JdbcTemplate jdbcTemplate) {
    try {
        ConnectionHolder holder = (ConnectionHolder) TransactionSynchronizationManager.getResource(jdbcTemplate.getDataSource());
        holder.getConnection().close();
        // set holder isVoid true
        holder.unbound();
    } catch (SQLException e1) {
        e1.printStackTrace();
    }
}

 

写在最后 

以上问题的分析和处理是通过debug下面的方法得出的,所以遇到问题查看源码确实是一种非常好的方法。

org.springframework.jdbc.core.JdbcTemplate#execute(org.springframework.jdbc.core.PreparedStatementCreator, org.springframework.jdbc.core.PreparedStatementCallback<T>)