c3p0 APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks


2018-01-04 15:02:03,319 ---com.mchange.v2.async.ThreadPoolAsynchronousRunner: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@4d6c4ebb -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!

先說說APPARENT DEADLOCK!!!​什么情況下會拋出這樣的異常?

通過看源碼,源碼是個好東西,有個檢測死鎖的DeadlockDetector​,每隔一段時間就會檢測一次,是一個TimerTask,里面是這樣寫的:

current = (LinkedList) pendingTasks.clone();​

if ( current.equals( last ) ){

               logger.warning(this + " -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!");

}​

解釋一下current和last

代碼里這兩個對象分別是一個LinkedList

current用來記錄當前等待獲取連接的AcquireTask​

last用來記錄上次等待獲取連接的AcquireTask​

如果二者相等的話,C3P0認為是死鎖,拋出警告

什么情況下會出現這樣的異常?

1.數據庫連接不上的話,會報這樣的異常​,檢查數據源配置是否正確?

我在本地測試,沒有配置​checkoutTime(獲取連接的超時時間)這個參數,20根線程並發發起連接,檢測死鎖的線程的線程,試想,在某次檢測過程中發現18個等待連接的任務,那么在下一次檢測的時候,這18個連接任務,仍舊沒有連上數據庫,可能是數據庫連接配置錯誤,檢查數據源配置信息,滿足出這個錯誤的條件,當然就會報APPARENT DEADLOCK!!!

2.在緩存中存在Statement,來說說這個

網上有人回答這個問題,說是設置c3p0.maxStatements=0,為啥設置一下這個就OK了呢?

這里說說我個人思考,因為在數據庫里的Statement的緩存都是在連接基礎上了,存在緩存了,這里我理解就是就是占用了數據庫的連接數,而申請新的連接的過程中,在達到連接數​最大時,檢測死鎖的線程又可能會檢測出2次等待連接是AcquireTask相等,就會拋出異常。

My workaround: 
In hibernate.cfg.xml: 

Code:
<property name="hibernate.c3p0.max_statements">0</property>

In c3p0.properties:

Code:
c3p0.maxStatements=0
c3p0.maxStatementsPerConnection=100

For such setting my multithreaded applications runs with no APPARENT DEADLOCK error (finally and ... hopefully that this problem is really solved). 
My app running quite fast so I guess (and I believe) that Statement caching is working. Statements caching is crucial for me because of performance. In other words I couldn't just turn Statement caching off (*). 
As far as I can see turning Statement caching off (this global statement caching) is one (or maybe the only one) solution to get rid of APPARENT DEADLOCK errors. 
Damn, I really would like to have time to have a look at c3p0 source code and figure out where is the reason of those fu!@#$% errors (Oracle JDBC or Hibernate or c3p0). 

總結一下:就是用戶申請新的連接的時候,舊的連接又沒有及時釋放,那么就會拋出​APPARENT DEADLOCK!!!的異常了。

本文轉自:http://blog.sina.com.cn/s/blog_7b9948fd0102vyuh.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM