Weblogic常見故障常:JDBC Connection Pools
WebLogic Server中數據庫連接池是一個經常出問題的地方,總結一下出問題的原因和解決辦法。一、數據庫連接泄漏
此類問題一般都是由於開發人員沒有正確關閉數據庫連接造成的。比如使用完Connection後,沒有調用Connection.close()方法。
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)
問題解決後,把三個屬性設置回先前的值。
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){}
}
二、數據庫連接不夠用
導致數據庫連接不夠用的原因主要有:①某些程序占用connection時間過長,如果多個用戶同時使用這些程序,則會導致連接不夠用。
②線程死鎖,無法釋放connection。
1、診斷方法
①監控參數:Waiting For Connection High Count
[domain_name]-> Enviroment -> Servers -> [Server] -> Monitoring -> JDBC查看參數:Waiting For Connection High Count
如果沒有此參數,手工添加進來,該參數表示在沒有可用連接的情況下,應用程序等待連接的最大個數。調整後的連接池最大值 = 調整前的連接池最大值 + Waiting For Connection High Count。一般來說,數據庫連接池的大小與最佳並發用戶數相當。
②在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.java:344)
at troubleshooting.servlets.JdbcConnections.service(JdbcConnections.java:80)
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)
如果此時觀察connection的監控,會發現所有connection 都是Active,而且還有大量請求等待connection。
2、解決方法
①提高Maximum Capacity數量,該值一般略大於峰值情況下的數據庫連接數。Services > JDBC > Connection Pools > BankConnectionPool > Configuration > Connections
②重點檢查synchronize代碼段和涉及數據庫鎖的代碼。如果有必要,可以查看thread dump,看看線程在忙什麼和等什麼。
三、數據庫連接使用超時
此類問題一般是由於某些數據庫操作時間比較長,超過了Inactive connection timeout的設置。
1、診斷方法
在Server Log中,明確有下列提示,並且在提示後拋出應用異常:
Forcibly releasing inactive resource "weblogic.jdbc.common.internal.ConnectionEnv@132967d" back into the pool BankConnectionPool".這裏無法列出應用異常,因為每個應用都不一樣,不過很有可能會拋出空指針異常,因為Connection被強製放回池中了,繼續使用一個空對象會拋出該異常。
2、解決方法
在高級參數中,提高Inactive connection timeout數量。
Services > JDBC > Connection Pools > BankConnectionPool > Configuration > Connections
四、事務超時
此類問題一般是由於某些數據庫操作時間比較長,超過了JTA Timeout Seconds的設置。
1、診斷方法
在Server Log中,明確拋出異常:
weblogic.transaction.internal.TimedOutException: Transaction timed out after 300 seconds
2、解決方法
提高Services > JTA Configuration > Timeout Seconds數量。
注意這個參數應該小於Inactive connection timeout的值,因為事務必須在連接超時前完成。如果想分析究竟是哪些SQL語句導致事務超時,可以打開日誌AdminServer > Logging > JDBC,選中Enable JDBC Logging,並設置JDBC Log File Name。
原帖地址:https://maping930883.blogspot.com/2009/03/wls040jdbc-connection.html
最後更新:2017-04-03 12:56:18