我正在尝试使用BasicDataSource在spring应用程序中与JDBCTemplate池连接。从我读过的所有内容来看,这应该非常简单:只需在XML中配置BasicDataSource,将数据源注入bean,然后在setter方法中创建一个新的JDBCTemplate。
当我这样做时,我注意到我的表现非常糟糕。然后我切换到Spring的SingleConnectionDataSource,只是为了看看会发生什么,我的表现得到了更好 。我开始使用分析器工具进行调查,我注意到在使用BasicDataSource时,正在为每个查询创建一个新连接。
进一步调查,我可以看到查询完成后连接的关闭位置。特别是在Spring的DataSourceUtil类中:
public static void doReleaseConnection(Connection con, DataSource dataSource) throws SQLException {
if (con == null) {
return;
}
if (dataSource != null) {
ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
if (conHolder != null && connectionEquals(conHolder, con)) {
// It's the transactional Connection: Don't close it.
conHolder.released();
return;
}
}
// Leave the Connection open only if the DataSource is our
// special SmartDataSoruce and it wants the Connection left open.
if (!(dataSource instanceof SmartDataSource) || ((SmartDataSource) dataSource).shouldClose(con)) {
logger.debug("Returning JDBC Connection to DataSource");
con.close();
}
}
我注意到的是'SmartDataSource'有一些特殊的逻辑,它使连接保持打开状态。这部分解释了我所看到的行为:由于SingleConnectionDataSource实现了SmartDataSource,因此连接未关闭。但是,我认为通过使用BasicDataSource,连接上的close()方法只会返回到池的连接。但是,当我查看我的探查器中发生的事情时,实际上是在我的sybase连接上调用close方法:不是像我希望看到的任何类型的“池连接包装器”。
最后一件事(这是我现在要研究的内容):我使用TransactionTemplate进行一些查询(涉及对数据库的提交),但是简单查询不在transactionTemplate中。我不知道这是否与问题有关。
编辑1:
好的,在稍微关闭项目之后,终于有了更多时间进行调查,这是一个非常简单的测试,显示问题
public class DBConnectionPoolTest {
@Autowired
@Qualifier("myDataSource")
private DataSource dataSource;
@Test
public void test() throws Exception{
JdbcTemplate template = new JdbcTemplate(dataSource);
StopWatch sw = new StopWatch();
sw.start();
for(int i=0; i<1000; i++){
template.queryForInt("select count(*) from mytable");
}
sw.stop();
System.out.println("TIME: " + sw.getTotalTimeSeconds() + " seconds");
}}
以下是我的两个数据源配置:
<bean id="myDataSource" class="org.springframework.jdbc.datasource.SingleConnectionDataSource">
<property name="driverClassName" value="${db.driver}" />
<property name="url" value="${db.url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
</bean>
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${db.driver}" />
<property name="url" value="${db.url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
</bean>
当我使用第一个配置运行测试时,大约需要2.1秒。当我使用第二种配置运行它时,大约需要4.5秒。我在BasicDataSource上尝试了各种参数,比如设置maxActive = 1和testOnBorrow = false,但没有什么区别。
答案 0 :(得分:0)
我认为我的问题是我的sybase的jdbc库已经过时了。