日期:2014-05-16  浏览次数:20510 次

WLS_040:常见故障之八:JDBC Connection Pools
声明:该博文转自http://maping930883.blogspot.com,热爱java,热爱生活

WebLogic Server中,数据库连接池是一个经常出问题的地方。下面就总结一下出问题的原因和解决办法。

1.数据库连接泄漏
此类问题一般都是由于开发人员没有正确关闭数据库连接造成的。比如,使用完Connection后,没有调用Connection.close()方法。
1.1. 诊断方法
在Console中,找到Connection Pools Tab 和Diagnostics,设置以下属性(不同版本可能略有区别)
Enable Connection Leak Profiling 启用连接池泄漏的监控。
Enable Connection Profiling 启用连接池监控。
Inactive Connection Timeout 100 表示100秒后强制回收无效连接。默认0,表示使用完才释放回连接池。
无需重启,查看server的log,查找“A JDBC pool connection leak was detected”,如果有,看看是哪个类引起的。
下面是一个数据库连接泄漏的例子:
A JDBC pool connection leak was detected.
A connection leak occurs when a connection obtained from the pool was not closed explicitly by calling close() and then was disposed by the garbage collector and returned to the connection pool.
The following stack trace at create shows where the leaked connection was created.
Stack trace at connection create:

at weblogic.jdbc.wrapper.JTAConnection.init(JTAConnection.java:90)
at weblogic.jdbc.jta.DataSource.getConnection(DataSource.java:468)
at weblogic.jdbc.jta.DataSource.connect(DataSource.java:410)
at weblogic.jdbc.common.internal.RmiDataSource.getConnection(RmiDataSource.java:344)
at troubleshooting.servlets.JdbcConnections.service(JdbcConnections.java:97)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at weblogic.servlet.internal.ServletStubImpl$ServletInvocationAction.run(ServletStubImpl.java:1077)
at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:465)
at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:348)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:7047)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:121)
at weblogic.servlet.internal.WebAppServletContext.invokeServlet(WebAppServletContext.java:3902)
at weblogic.servlet.internal.ServletRequestImpl.execute(ServletRequestImpl.java:2773)
at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:224)
at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:183)

问题解决后,把三个属性设置回先前的值。

1.2. 解决方法
正确的关闭数据库连接。具体代码如下:
Connection conn = null;
ResultSet rs = null;
preparedStatement pss = null;
try {
conn = dataSource.getConnection(USERID,pASSWORD);
pss = conn.prepareStatement("SELECT SAVESERIALZEDDATA FROM SESSION.pINGSESSION3DATA WHERE SESSIONKEY = ?");
pss.setString(1,sessionKey);
rs = pss.executeQuery();
pss.close();
} catch (Throwable t) {
// 错误处理
} finally {
try {
if (conn != null) conn.close();
} catch (Exception e){}
}

2.数据库连接不够用
导致数据库连接不够用的原因主要有:
(1)某些程序占用connection时间过长,如果多个用户同时使用这些程序,则会导致连接不够用。
(2)线程死锁,无法释放connection。

2.1. 诊断方法
(1)监控参数:Waiting For Connection High Count
[domain_name]-> Enviroment -> Servers -> [Server] -> Monitoring -> JDBC查看参数:Waiting For Connection High Count
如果没有此参数,手工添加进来,该参数表示在没有可用连接的情况下,应用程序等待连接的最大个数。
调整后的连接池最大值 = 调整前的连接池最大值 + Waiting For Connection High Count。
一般来说,数据库连接池的大小与最佳并发用户数相当。

(2)在Server Log中,明确抛出下列异常:
java.sql.SQLException: Internal error: Cannot obtain XAConnection weblogic.common.resourcepool.ResourceLimitException: No resources currently available in pool BankConnectionPool to allocate to applications, please increase the size of the pool and retry..
at weblogic.jdbc.jta.DataSource.refreshXAConnAndEnlist(DataSource.java:1493)
at weblogic.jdbc.jta.DataSource.getConnection(DataSource.java:455)
at weblogic.jdbc.jta.DataSource.connect(DataSource.java:410)
at weblogic.jdbc.common.internal.RmiDataSource.getConnection(RmiDataSource.j