批量更新通过JDBC批处理给人的SQLException通过TransactionImp

问题描述:

我使用EJB3的Oracle数据库JDBC批量更新通过JDBC批处理给人的SQLException通过TransactionImp

我正在开发一个应用程序,我必须解雇25000 UPDATE查询。

我的代码如下:

public int updateStatus(List<String> idList) { 
    Connection connection = getConnection(); // Connection initialized properly for oracle db 
    statement = connection.createStatement(); 
    String sql = null; 
    for (String id : idlist) { // idList is properly filled 
     sql = "UPDATE TBLTEST SET STATUS = 'FIXED' WHERE ID = '" + id + "'"; 
     statement.addBatch(sql); 
    } 
    int[] affectedRecords = statement.executeBatch(); 
} 

请注意,在这种方法写的类,被注释为

@TransactionManagement(TransactionManagementType.CONTAINER) 

此代码工作高达8000个查询完美的罚款。欲了解更多id S,它抛出以下异常:

org.jboss.util.NestedSQLException: Transaction TransactionImple < ac, BasicAction: 0:ffffc0a80272:1652:56bd6be5:57e status: ActionStatus.ABORTED > cannot proceed STATUS_ROLLEDBACK; - nested throwable: (javax.transaction.RollbackException: Transaction TransactionImple < ac, BasicAction: 0:ffffc0a80272:1652:56bd6be5:57e status: ActionStatus.ABORTED > cannot proceed STATUS_ROLLEDBACK) 
    at org.jboss.resource.adapter.jdbc.WrapperDataSource.checkTransactionActive(WrapperDataSource.java:165) 
    at org.jboss.resource.adapter.jdbc.WrappedConnection.checkTransactionActive(WrappedConnection.java:843) 
    at org.jboss.resource.adapter.jdbc.WrappedConnection.checkStatus(WrappedConnection.java:858) 
    at org.jboss.resource.adapter.jdbc.WrappedConnection.checkTransaction(WrappedConnection.java:835) 
    at org.jboss.resource.adapter.jdbc.WrappedConnection.createStatement(WrappedConnection.java:183) 

任何人都可以用除帮助吗?

+0

一个小建议,让你的代码更快,更好。希望这会让你摆脱这个例外。使用preparedStatement()而不是createStatement()。有关以下链接的更多信息。 http://viralpatel.net/blogs/batch-insert-in-java-jdbc/ – justRadojko

+0

@justRadojko,谢谢你的回复。但是我不能使用'PreparedStatement',因为它不会以成功查询更新记录的方式给出确切的结果,即'affectedRecords'会给我一个满-2值的数组。 – RAS

最佳猜测:通过使用单个SQL语句而不是PreparedStatement,您强制驱动程序将所有语句(> 400k字符数据)发送到数据库和数据库,以解析所有400k字符,这将在一些时间和破坏的东西(例外情况不明确,因为它隐藏了造成异常的地方或破坏)。

如何解决:

围棋的“不太多”声明同时个别批次 - 说... 1000:

public int updateStatus(List<String> idList) { 
    List<Integer> affectedRecords = new ArrayList<Integer>(idList.size()); 
    try(Connection connection = getConnection(); 
     Statement statement = connection.createStatement()) { 
     int count = 0; 
     for (String id : idList) {   
      statement.addBatch("UPDATE TBLTEST SET STATUS = 'FIXED' WHERE ID = '" + id + "'"); 
      //Execute after 1000 rows 
      if(++count % 1000 == 0) { 
       int[] result = statement.executeBatch(); 
       //Utility Method - you need to implement to add int[] into the List 
       addResults(affectedRecords, result); 
       statement.clearBatch();    
      } 
     } 
     //In need of final execute? 
     if(count % 1000 > 0) { 
      // For good measure execute once more 
      int[] result = statement.executeBatch(); 
      //Utility Method - you need to implement to add int[] into the List 
      addResults(affectedRecords, result);  
     }    
    } catch(SQLException se) { 
     se.printStackTrace(); 
    } 
} 
+0

谢谢Jan,这在一定程度上有所帮助。但达到某一点后,这也失败了。 – RAS