DBCP连接池优化之启用PoolPreparedStatements

一、背景

公司的应用系统后台运行日志显示,系统经常出现“ORA-01000: maximum open cursors exceeded ”错误,即“超出最大可打开的游标数”。
应用系统采用SSH构建,使用commons-dbcp作为连接池,数据库为Oracle 10g。

二、分析处理

  • 查看游标使用情况
SELECT o.sid, osuser, machine, COUNT(*) num_curs
  FROM v$open_cursor o, v$session s
 WHERE user_name = &user_name
   AND o.sid = s.sid
 GROUP BY o.sid, osuser, machine
 ORDER BY num_curs DESC;
  • 查看游标执行情况
SELECT o.sid, q.sql_text
  FROM v$open_cursor o, v$sql q
 WHERE q.hash_value = o.hash_value
   AND o.sid = &sid;
  • 怀疑使用hql语句或sql语句查询时,直接将参数作为语句字符串的一部分,而不是使用绑定变量,导致Oracle执行相同逻辑的SQL时每次创建新的执行计划,使游标不断增加。如:
// 直接将参数作为hql语句字符串的一部分
String hql="from User u where u.username='"+userName+"'";
Query query = getSession.createQuery(hql);
query.list();
// 使用绑定变量
String hql="from User u where u.username=?";
Query query = getSession.createQuery(hql);
query.setString(1, userName);
query.list();

根据游标执行情况排查了产生游标数较多的hql或sql,排除了“未使用绑定变量,导致游标不断增加”的可能性。

  • 判断可能是DBCP连接池使用不当导致
    经互联网搜索,发现配置DBCP连接池启用参数poolPreparedStatements即可解决此问题。
    查看org.apache.commons.dbcp.BasicDataSource源码,可以看到:
/**
 * Prepared statement pooling for this pool. When this property is set to <code>true</code>
 * both PreparedStatements and CallableStatements are pooled.
 */
protected boolean poolPreparedStatements = false;

/**
 * Returns true if we are pooling statements.
 * 
 * @return true if prepared and callable statements are pooled
 */
public synchronized boolean isPoolPreparedStatements() {
    return this.poolPreparedStatements;
}

即启用poolPreparedStatements后,PreparedStatements 和CallableStatements 都会被缓存起来复用,即相同逻辑的SQL可以复用一个游标,这样可以减少创建游标的数量。

三、参考文章

连接池优化之启用PoolPreparedStatements
关于ORA-01000: maximum open cursors exceeded” 问题分析总结

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
使用DBCP连接需要在配置文件中设置以下属性: 1. 驱动类名(driverClassName):数据库驱动程序的名称,例如com.mysql.jdbc.Driver。 2. 数据库连接URL(url):连接到数据库的URL,例如jdbc:mysql://localhost:3306/test。 3. 数据库用户名(username):连接到数据库所需的用户名。 4. 数据库密码(password):连接到数据库所需的密码。 5. 初始连接数(initialSize):连接在启动时创建的初始连接数。 6. 最小空闲连接数(minIdle):连接中保留的最小空闲连接数。 7. 最大活动连接数(maxActive):连接中同时可分配的最大活动连接数。 8. 最大等待时间(maxWait):等待连接分配连接的最长时间(以毫秒为单位)。 9. 连接名(poolName):连接的名称。 下面是一个示例配置文件: ```xml <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/test" /> <property name="username" value="root" /> <property name="password" value="password" /> <property name="initialSize" value="5" /> <property name="minIdle" value="2" /> <property name="maxActive" value="20" /> <property name="maxWait" value="10000" /> <property name="poolPreparedStatements" value="true" /> <property name="maxOpenPreparedStatements" value="100" /> <property name="poolName" value="MyDBCP" /> </bean> ``` 在上面的配置中,我们使用了org.apache.commons.dbcp.BasicDataSource类,它是DBCP连接的实现类。我们设置了MySQL数据库的驱动程序名称、URL、用户名和密码。我们还设置了连接的一些属性,例如初始连接数、最小空闲连接数、最大活动连接数和最大等待时间。最后,我们指定了连接的名称为MyDBCP

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值