2013-09-24 91 views
3

我有一些工作線程正在運行,使用MySQL和mysql-connector-java-5.1.20。 當我殺死一些SQL語句(使用從mysql客戶端kill「連接ID」),Java線程掛起,這應該會引發一些異常。java應用程序,線程在殺死MySQL連接後掛起

jstack打印:

"quartzBase$child#45e3dd3c_Worker-3" prio=10 tid=0x00007f960004c800 nid=0x713d runnable [0x00007f943b3a0000] 
    java.lang.Thread.State: RUNNABLE 
     at java.net.PlainSocketImpl.socketAvailable(Native Method) 
     at java.net.PlainSocketImpl.available(PlainSocketImpl.java:472) 
     - locked <0x00007f9e11fe13a8> (a java.net.SocksSocketImpl) 
     at java.net.SocketInputStream.available(SocketInputStream.java:217) 
     at com.mysql.jdbc.util.ReadAheadInputStream.available(ReadAheadInputStream.java:232) 
     at com.mysql.jdbc.MysqlIO.clearInputStream(MysqlIO.java:981) 
     at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2426) 
     at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2651) 
     at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2677) 
     - locked <0x00007f9e17de2b50> (a com.mysql.jdbc.JDBC4Connection) 
     at com.mysql.jdbc.ConnectionImpl.rollbackNoChecks(ConnectionImpl.java:4863) 
     at com.mysql.jdbc.ConnectionImpl.rollback(ConnectionImpl.java:4749) 
     - locked <0x00007f9e17de2b50> (a com.mysql.jdbc.JDBC4Connection) 
     at org.apache.commons.dbcp.DelegatingConnection.rollback(DelegatingConnection.java:368) 
     at org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.rollback(PoolingDataSource.java:323) 
     at org.hibernate.transaction.JDBCTransaction.rollbackAndResetAutoCommit(JDBCTransaction.java:217) 
     at org.hibernate.transaction.JDBCTransaction.rollback(JDBCTransaction.java:196) 
     at org.springframework.orm.hibernate3.HibernateTransactionManager.doRollback(HibernateTransactionManager.java:676) 
     at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:845) 
     at org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.java:822) 
     at org.springframework.transaction.interceptor.TransactionAspectSupport.completeTransactionAfterThrowing(TransactionAspectSupport.java:430) 
     at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:112) 
     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) 
     at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) 
     at $Proxy1021.process(Unknown Source) 

使用jvmtop,我看到這一點:

JvmTop 0.8.0 alpha - 22:48:37, amd64, 24 cpus, Linux 2.6.32-35, load avg 11.53 
http://code.google.com/p/jvmtop 

Profiling PID 27403: com.caucho.server.resin.Resin --root-dir 

    36.41% ( 0.22s) com.mysql.jdbc.util.ReadAheadInputStream.available() 
    33.42% ( 0.20s) ....opensymphony.xwork2.conversion.impl.DefaultTypeConve() 
    30.17% ( 0.18s) com.mysql.jdbc.util.ReadAheadInputStream.fill() 
    0.00% ( 0.00s) com.rabbitmq.client.impl.Frame.readFrom() 

工作線程絕不會接受新的任務。

有什麼想法嗎?

+3

*當我殺死一個SQL語句(使用kill「connection id」from mysql client)*當你殺死一個像這樣的SQL語句,誰知道爲什麼,一隻小貓死了= \ –

+1

爲什麼它應該通過異常?如果你從側面殺死查詢,我懷疑java線程要等待Godot ... – Fildor

+0

hi @LuiggiMendoza,當任務被取消時,它在MySQL上觸發的SQL不會停止執行。所以我們有聲明被殺害。 –

回答

0

根據MySQL documentation「kill connection thread_id」應該終止與給定的thread_id相關的連接。但它看起來沒有發生(在這種情況下,Java線程將永遠等待答案)。也許你可以使用某些網絡工具(例如netstat)驗證連接是否真正關閉。

我已經遇到過掛起的MySQL連接,不得不求助於使用JDBC連接參數socketTimeout(但要小心:socketTimeout需要大於完成最長運行查詢所需的時間)。您也可以嘗試使用QueryTimeout作爲準備好的語句。