Spring 之防止连接泄露的处理办法,Java 开发必会技术
private JdbcTemplate jdbcTemplate;
public static class UserServiceRunner extends Thread{
private TestJdbcService testJdbcService;
private String name;
public UserServiceRunner(TestJdbcService testJdbcService,String name) {
this.testJdbcService = testJdbcService;
this.name = name;
}
@Override
public void run() {
testJdbcService.logon(name);
}
public long getThreadID() {
return Thread.currentThread().getId();
}
}
public void logon(String name){
try {
Connection connect = jdbcTemplate.getDataSource().getConnection();
String sql = "update zhu_test set last_time = ? where name = ?";
jdbcTemplate.update(sql, System.currentTimeMillis(),name);
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void sleep(long time){
try {
Thread.sleep(time);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void reportConn(DruidDataSource dataSource){
System.out.println("连接数[active]-[" +
dataSource.getActiveCount()+"]");
}
public static void asynclogin(TestJdbcService testJdbcService,String name){
UserServiceRunner runner = new UserServiceRunner(testJdbcService,name);
System.err.println(Thread.currentThread().getName()+"ID:"+runner.getThreadID());
runner.start();
}
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("file:src/main/resources/applicationContext.xml");
TestJdbcService testJdbcService = (TestJdbcService) ctx.getBean("testJdbcService");
DruidDataSource druidDataSource = (DruidDataSource) ctx.getBean("dataSource");
testJdbcService.reportConn(druidDataSource);
testJdbcService.asynclogin(testJdbcService,"tom");
testJdbcService.sleep(500);
testJdbcService.reportConn(druidDataSource);
testJdbcService.sleep(2000);
testJdbcService.reportConn(druidDataSource);
testJdbcService.asynclogin(testJdbcService,"jack");
testJdbcService.sleep(500);
testJdbcService.reportConn(druidDataSource);
testJdbcService.sleep(2000);
testJdbcService.reportConn(druidDataSource);
}
}
运行结果:

由于我使用的是阿里的数据源,没有找到获取空闲连接的方法
分析如下(引自网络)

解决办法:
①使用 DataSourceUtils

将上述获取连接的方式改为 DataSourceUtils 的形式来获取连接。
public void logon(String name){
try {
//Connection connect = jdbcTemplate.getDataSource().getConnection();
Connection connect = DataSourceUtils.getConnection(jdbcTemplate.getDataSource());
String sql = "update zhu_test set last_time = ? where name = ?";
jdbcTemplate.update(sql, System.currentTimeMillis(),name);
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
然后查看运行结果:

并没有数据连接泄露。
但是这样仅仅是在配置事务的时候不会出现连接泄露,如果将事务注释之后,还是会出现一定的连接泄漏。
将配置文件中的事务注释之后,执行结果

分析如下(引自网络)
issolve/70/gravity/SouthEast)
杜绝上述情况连接泄露的方式就是手动关闭连接。
②使用 TransactionAwareDataSourceProxy
评论