1.出現的問題
日志文件沒有新的輸出。
2.問題分析
dump出堆棧,如下:
"main" prio=10 tid=0x000000005de12000 nid=0x27e8 runnable [0x0000000040240000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at java.io.DataInputStream.readFully(DataInputStream.java:178)
at java.io.DataInputStream.readFully(DataInputStream.java:152)
at net.sourceforge.jtds.jdbc.SharedSocket.readPacket(SharedSocket.java:842)
at net.sourceforge.jtds.jdbc.SharedSocket.getNetPacket(SharedSocket.java:723)
- locked <0x0000000759fd9f90> (a java.util.ArrayList)
at net.sourceforge.jtds.jdbc.ResponseStream.getPacket(ResponseStream.java:466)
at net.sourceforge.jtds.jdbc.ResponseStream.read(ResponseStream.java:135)
at net.sourceforge.jtds.jdbc.ResponseStream.readString(ResponseStream.java:290)
at net.sourceforge.jtds.jdbc.ResponseStream.readNonUnicodeString(ResponseStream.java:274)
at net.sourceforge.jtds.jdbc.TdsData.readData(TdsData.java:936)
at net.sourceforge.jtds.jdbc.TdsCore.tdsRowToken(TdsCore.java:3007)
at net.sourceforge.jtds.jdbc.TdsCore.nextToken(TdsCore.java:2270)
at net.sourceforge.jtds.jdbc.TdsCore.getNextRow(TdsCore.java:765)
at net.sourceforge.jtds.jdbc.JtdsResultSet.next(JtdsResultSet.java:596)
at org.apache.commons.dbcp.DelegatingResultSet.next(DelegatingResultSet.java:207)
at org.apache.commons.dbcp.DelegatingResultSet.next(DelegatingResultSet.java:207)
at com.jd.cis.worker.OppProductWorker.importData(OppProductWorker.java:310)
at com.jd.cis.worker.BaseWorker.importDataSource(BaseWorker.java:416)
at com.jd.cis.worker.OppProductWorker.doRun(OppProductWorker.java:276)
at com.jd.cis.worker.BaseWorker.run(BaseWorker.java:448)
at com.jd.cis.worker.OppProductWorker.main(OppProductWorker.java:564)
上面有鎖,對應的代碼為
statement.setFetchSize(1000);
.....
resultSet = statement.executeQuery();
while (resultSet.next()) {
......
}
查詢相關文檔,了解到JTDS默認的socketTimeout為0,即讀取數據沒有超時時間。
當數據鏈接意外終止的時候,JDTS可能檢測不到,就會一直等待數據,阻塞進程。
在本地重現該問題,在循環體里面設置斷點,進入斷點后,斷掉所有網絡鏈接,取消斷點,繼續運行,發現程序被一致阻塞了。
當設置socketTimeout為60秒,重試,程序阻塞60秒后拋出異常。
該問題在查詢SQLServer數據庫,大數據量查詢,分批獲取的時候,容易出現
3.解決方案
為jdts的url鏈接中加上socketTimeout(單位秒)的設置,或在dbcp中如下設置
<property name="connectionProperties" value="characterEncoding=UTF-8;socketTimeout=60"/>
這個參數和mybatis的defaultStatementTimeout 參數是不一樣的
同時Worker中加入異常捕獲重試機制
日志文件沒有新的輸出。
2.問題分析
dump出堆棧,如下:
"main" prio=10 tid=0x000000005de12000 nid=0x27e8 runnable [0x0000000040240000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at java.io.DataInputStream.readFully(DataInputStream.java:178)
at java.io.DataInputStream.readFully(DataInputStream.java:152)
at net.sourceforge.jtds.jdbc.SharedSocket.readPacket(SharedSocket.java:842)
at net.sourceforge.jtds.jdbc.SharedSocket.getNetPacket(SharedSocket.java:723)
- locked <0x0000000759fd9f90> (a java.util.ArrayList)
at net.sourceforge.jtds.jdbc.ResponseStream.getPacket(ResponseStream.java:466)
at net.sourceforge.jtds.jdbc.ResponseStream.read(ResponseStream.java:135)
at net.sourceforge.jtds.jdbc.ResponseStream.readString(ResponseStream.java:290)
at net.sourceforge.jtds.jdbc.ResponseStream.readNonUnicodeString(ResponseStream.java:274)
at net.sourceforge.jtds.jdbc.TdsData.readData(TdsData.java:936)
at net.sourceforge.jtds.jdbc.TdsCore.tdsRowToken(TdsCore.java:3007)
at net.sourceforge.jtds.jdbc.TdsCore.nextToken(TdsCore.java:2270)
at net.sourceforge.jtds.jdbc.TdsCore.getNextRow(TdsCore.java:765)
at net.sourceforge.jtds.jdbc.JtdsResultSet.next(JtdsResultSet.java:596)
at org.apache.commons.dbcp.DelegatingResultSet.next(DelegatingResultSet.java:207)
at org.apache.commons.dbcp.DelegatingResultSet.next(DelegatingResultSet.java:207)
at com.jd.cis.worker.OppProductWorker.importData(OppProductWorker.java:310)
at com.jd.cis.worker.BaseWorker.importDataSource(BaseWorker.java:416)
at com.jd.cis.worker.OppProductWorker.doRun(OppProductWorker.java:276)
at com.jd.cis.worker.BaseWorker.run(BaseWorker.java:448)
at com.jd.cis.worker.OppProductWorker.main(OppProductWorker.java:564)
上面有鎖,對應的代碼為
statement.setFetchSize(1000);
.....
resultSet = statement.executeQuery();
while (resultSet.next()) {
......
}
查詢相關文檔,了解到JTDS默認的socketTimeout為0,即讀取數據沒有超時時間。
當數據鏈接意外終止的時候,JDTS可能檢測不到,就會一直等待數據,阻塞進程。
在本地重現該問題,在循環體里面設置斷點,進入斷點后,斷掉所有網絡鏈接,取消斷點,繼續運行,發現程序被一致阻塞了。
當設置socketTimeout為60秒,重試,程序阻塞60秒后拋出異常。
該問題在查詢SQLServer數據庫,大數據量查詢,分批獲取的時候,容易出現
3.解決方案
為jdts的url鏈接中加上socketTimeout(單位秒)的設置,或在dbcp中如下設置
<property name="connectionProperties" value="characterEncoding=UTF-8;socketTimeout=60"/>
這個參數和mybatis的defaultStatementTimeout 參數是不一樣的
同時Worker中加入異常捕獲重試機制