近期寫了一個數據庫採集程序,大概過程是將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
採集的代碼也加上事務