一次c3p0連線池連線異常錯誤的排查
最近寫了一個數據庫採集程式,大概過程是將SQLSERVER資料庫的資料定時採集到Oracle資料庫。1小時出一次資料,每次資料量在2W左右。環境採用Sping3+hibernate4,資料庫連線池採用C3p0
奇怪的時候每隔一段時間都會報:“c3p0 connection is already closed”
我開始的資料庫連線池配置如下:oracle資料庫開啟事務,而採集的sqlserver資料庫沒有開啟事務
發現了問題,我首先在c3p0上加上除錯資訊的配置: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.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
採集的程式碼也加上事務