1. 程式人生 > >一次c3p0連線池連線異常錯誤的排查

一次c3p0連線池連線異常錯誤的排查

最近寫了一個數據庫採集程式,大概過程是將SQLSERVER資料庫的資料定時採集到Oracle資料庫。1小時出一次資料,每次資料量在2W左右。環境採用Sping3+hibernate4,資料庫連線池採用C3p0

奇怪的時候每隔一段時間都會報:“c3p0 connection is already closed” 

我開始的資料庫連線池配置如下:oracle資料庫開啟事務,而採集的sqlserver資料庫沒有開啟事務

jdbc.driverClass=oracle.jdbc.OracleDriver
jdbc.jdbcUrl=jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE=on)(ADDRESS=(PROTOCOL=TCP)(HOST=10.12.18.240)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=orcl)))
jdbc.user=appds
jdbc.password=appds
c3p0.acquireIncrement=5
c3p0.maxIdleTime=60
c3p0.maxPoolSize=80
c3p0.minPoolSize=10
c3p0.initialPoolSize=10
c3p0.maxStatements=0
c3p0.idleConnectionTestPeriod=60
c3p0.acquireRetryAttempts=30
c3p0.acquireRetryDelay=1000
c3p0.breakAfterAcquireFailure=false
c3p0.testConnectionOnCheckout=false

jdbcdata.driverClass=com.microsoft.sqlserver.jdbc.SQLServerDriver
jdbcdata.jdbcUrl=jdbc:sqlserver://10.12.18.241:1433;databaseName=data;
jdbcdata.user=cawasdatauser
jdbcdata.password=cawas606
c3p0ObsDataDB.maxPoolSize=30
發現了問題,我首先在c3p0上加上除錯資訊的配置

c3p0.debugUnreturnedConnectionStackTraces=true
c3p0.unreturnedConnectionTimeout=90 (我的連線超時時間是60s,所以這設定了90s)

applicationContext資料來源配置增加響應配置

<property name="breakAfterAcquireFailure" value="${c3p0.breakAfterAcquireFailure}" />
<property name="testConnectionOnCheckout" value="${c3p0.testConnectionOnCheckout}" />

果然發現很多未回收的連線,正常情況下超時未回收的連線會有一些,但是不會這麼多啊。

經查資料在hibernate sessionFacory中增加配置(http://hi.baidu.com/austincao/item/fc9907da3d854e44fa576861)

Spring3.1去掉了HibernateDaoSupport類。hibernate4需要通過getCurrentSession()獲取session。並且設定
<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop>

在Spring @Transactional宣告式事務管理,”currentSession”的定義為: 當前被 Spring事務管理器 管理的Session,此時應配置:
hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext。

另外在hibernate中使用sessionFactory.getCurrentSession()獲取session時,需要為方法宣告事務,為此將sqlserver

採集的程式碼也加上事務