2012-08-14 71 views
0

我有一個java webapp使用ibatis行處理程序加載一個非常大的數據集(innodb表中有100萬行)。該過程由石英調度程序作爲夜間cron作業運行。但是,處理6分鐘之後,它會死亡,並顯示以下堆棧跟蹤:Java Quartz Ibatis Cron問題

WARN [DefaultQuartzScheduler_Worker-8] MethodInvokingJobDetailFactoryBean$MethodInvokingJob.executeInternal(168) | Could not invoke method 'doBatch' on target object [[email protected]] 
org.springframework.jdbc.UncategorizedSQLException: SqlMapClient operation: encountered SQLException [ 
--- The error occurred in org/myCron/mySqlMap.xml. 
--- The error occurred while applying a result map. 
--- Check the mySqlMap.outputMapping. 
--- The error happened while setting a property on the result object. 
--- Cause: com.mysql.jdbc.CommunicationsException: Communications link failure due to underlying exception: 

** BEGIN NESTED EXCEPTION ** 

java.io.EOFException 

STACKTRACE: 

java.io.EOFException 
     at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1903) 
     at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2402) 
     at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2860) 
     at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:771) 
     at com.mysql.jdbc.MysqlIO.nextRow(MysqlIO.java:1289) 
     at com.mysql.jdbc.RowDataDynamic.nextRecord(RowDataDynamic.java:362) 
     at com.mysql.jdbc.RowDataDynamic.next(RowDataDynamic.java:352) 
     at com.mysql.jdbc.ResultSet.next(ResultSet.java:6106) 
     at org.apache.commons.dbcp.DelegatingResultSet.next(DelegatingResultSet.java:168) 
     at sun.reflect.GeneratedMethodAccessor71.invoke(Unknown Source) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
     at java.lang.reflect.Method.invoke(Method.java:592) 
     at com.ibatis.common.jdbc.logging.ResultSetLogProxy.invoke(ResultSetLogProxy.java:47) 
     at $Proxy10.next(Unknown Source) 
     at com.ibatis.sqlmap.engine.execution.SqlExecutor.handleResults(SqlExecutor.java:380) 
     at com.ibatis.sqlmap.engine.execution.SqlExecutor.handleMultipleResults(SqlExecutor.java:301) 
     at com.ibatis.sqlmap.engine.execution.SqlExecutor.executeQuery(SqlExecutor.java:190) 
     at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.sqlExecuteQuery(GeneralStatement.java:205) 
     at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.java:173) 
     at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithRowHandler(GeneralStatement.java:133) 
     at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryWithRowHandler(SqlMapExecutorDelegate.java:649) 
     at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryWithRowHandler(SqlMapSessionImpl.java:156) 
     at com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryWithRowHandler(SqlMapClientImpl.java:133) 
     at org.springframework.orm.ibatis.SqlMapClientTemplate$5.doInSqlMapClient(SqlMapClientTemplate.java:267) 
     at org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:165) 
     at org.springframework.orm.ibatis.SqlMapClientTemplate.queryWithRowHandler(SqlMapClientTemplate.java:265) 
     at org.myCron.doBatch(MyCron.java:57) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
     at java.lang.reflect.Method.invoke(Method.java:592) 
     at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:248) 
     at org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean$MethodInvokingJob.executeInternal(MethodInvokingJobDetailFactoryBean.java:165) 
     at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:66) 
     at org.quartz.core.JobRunShell.run(JobRunShell.java:191) 
     at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:516) 


** END NESTED EXCEPTION ** 

堆棧跟蹤非常模糊。我看到的唯一提示是'在設置結果對象的屬性時發生錯誤'。結果對象只有兩個屬性:一個字符串和一個整數。他們都允許空值,但我的選擇語句表明他們都沒有任何空值。他們都有一個合適的getter/setter(這是有道理的,因爲該過程在臨死前成功運行了一段時間)。每次cron運行時,它都會隨機死掉(所以它不會卡在特定的行上)。

注 - 方法'doBatch'確實存在,因爲那是啓動cron進程的方法。如果找不到doBatch,則無法成功處理第一千行。

我也試過在石英外面做這個工作,它也在那裏失效。我們嘗試增加MySQL的net_read_timeout,net_write_timeout和delayed_insert_timeout,但這些設置都沒有幫助解決問題。我也嘗試設置我的log4j設置爲DEBUG,我沒有得到任何有用的信息。

關於我可以試試的其他想法?

回答

0

由於某些原因,MySQL的聲音關閉了連接。檢查MySQL日誌,看看是否有任何東西出現。如有必要,打開MySQL的各種日誌記錄選項。另外,從您的應用程序開始打印調試數據(包括時間戳) - 只需打印所有內容,然後查看最後一個操作是什麼 - 也許您的代碼中有一些很少觸發的條件存在缺陷。

I.e.每次你跟MySQL交談之前都會記錄它。

+0

我應該注意的一件事是我的輸入數據集是靜態的。我正在執行大量數據集的單次一次導入。如果問題是由於「代碼中很少觸發有bug的情況」引起的,我認爲這個過程總是會在同一行失敗。每次我運行它,我都會失敗。關於MySQL日誌記錄選項,我已經將SQL的log4j設置爲DEBUG。 – David 2012-08-15 13:13:41

+0

@David不是應用程序日誌,即MySQL日誌。這不是一回事。如果你從MySQL中得到一個錯誤,那麼你應該看看它的位置。 – Ariel 2012-08-15 17:01:04