最近在作一個java項目的時候遇到一個十分奇怪的問題,想到你們可能也會遇到這樣的問題,因此在此發出來,但願你們遇到的時候可以快速解決!java
直入主題數據庫
問題:使用quartz進行定時任務自動執行的時候,用到hibernate進行數據庫交互,Tomcat運行中,會遇到在某個訪問先後無端中止運行,以後的定時任務所有卡住!緩存
問題解析:首先我從幾個方面考慮這個問題。session
一、quartz配置問題。spa
二、數據庫鏈接超時。hibernate
三、Tomcat自動清理或者超時。線程
四、quartz線程死鎖或阻塞。code
五、hibernate Session問題。blog
綜合考慮以上問題,一個一個考慮。首先,個人配置是沒有問題的,由於quartz的配置仍是很清晰和簡單的,通過反覆查看沒有問題。數據庫鏈接在我設置成1s週期的時候也是沒有問題的,同時也不會是第三個緣由。因爲個人quartz的線程設置都是使用默認的,並且我在線程列表中也看到,有10個線程,因此線程不夠用致使阻塞是不可能的。死鎖的問題我也不用考慮,由於每一個任務都是單獨存在的,沒有關聯。那就剩最後一個緣由了,說實話,最後一個緣由是我沒辦法的時候才忽然想到的,也是問題所在。rem
hibernate有本身的鏈接池,在使用的時候咱們新建的全部鏈接都會存在這個鏈接池中,若是你所建的新鏈接太多而不釋放,那麼就會致使你的新鏈接沒法建立,從而阻塞,這也是爲何程序中無端中止,並且沒i有任何錯誤的緣由。
那麼怎麼解決這個問題呢,使用Hibernate時,你們通常都記住了配置基本的那些選項,好比方言,緩存等,可是有一項配置卻很容易忘掉,這就是鏈接釋放模式:hibernate.connection.release_mode
這個配置項有三個選擇:after_statement/after_transaction/on_close,javadoc中能夠看出它們的用處,注意的一點是,若是不配置,默認是on_close,那麼若是沒有顯示的去調用session.close或其它關閉鏈接的方法的話,這個鏈接時不會被關閉的!在用到鏈接池的時候,就更會出現問題了,池中的鏈接會一直存在着而不會被關閉和回收!
具體的配置:<prop key="hibernate.connection.release_mode">after_transaction</prop>
放在你的hibernate配置裏面就能夠了。這樣咱們的鏈接自動釋放後就不會出現上述問題了。
PS:這個問題我解決了很長時間,網上的資料查了不少,浪費了不少時間,同時也有人遇到這樣的問題,可是解決方式都不太對症。最後發現了這個問題。終於解決了,寫在這裏,方便你們。儘可能不要在這個問題上浪費時間。
若是幫助到了你,請點贊,謝謝!
2015 12 16
今天又深刻的研究了一下,問題的源頭是鏈接池鏈接阻塞,因此我修改了數據源的鏈接回收時間,實驗有效。具體配置以下,你們能夠試試
<!-- 初始鏈接數目 --> <property name="initialSize" value="10"></property> <!-- 最大鏈接數目 --> <property name="maxActive" value="50"></property> <!-- 最大空閒鏈接數目 --> <property name="maxIdle" value="50"></property> <!-- 最小空閒鏈接數目 --> <property name="minIdle" value="0"></property> <!-- 超時等待時間以毫秒爲單位 --> <property name="maxWait" value="10000"></property> <!-- #是否自動回收超時鏈接 --> <property name="removeAbandoned" value="true"></property> <!-- #設置被遺棄的鏈接的超時的時間(以秒數爲單位),即當一個鏈接被遺棄的時間超過設置的時間,則它會自動轉換成可利用的鏈接。默認的超時時間是300秒。 --> <property name="removeAbandonedTimeout" value="60"></property> <!-- #是否在自動回收超時鏈接的時候打印鏈接的超時錯誤 --> <!-- <property name="logAbandoned" value="true"></property> -->