Java调用MySQL存储过程批量插入遇异常如何继续执行剩余插入
解决方案
你需要从JDBC配置、Java代码逻辑调整、MySQL存储过程改造三个层面处理,实现单条数据插入异常不中断整体批量执行:
1. JDBC连接参数配置
在MySQL JDBC连接URL中添加如下参数:jdbc:mysql://<数据库地址>:<端口>/<库名>?rewriteBatchedStatements=true&continueBatchOnError=true
rewriteBatchedStatements=true:开启MySQL批量执行优化,大幅提升批量操作性能continueBatchOnError=true:批量执行过程中遇到单条语句异常时,不终止后续语句执行,是实现容错的核心参数
2. Java代码逻辑调整
修改批量执行逻辑,捕获BatchUpdateException获取逐条执行结果,避免单次异常触发全量回滚:
public void insertXml(ArrayList<String> xmlCollection) throws SQLException { Connection connection = null; CallableStatement statement = null; try { connection = DbConnector.getConnection(); Application.getAppInstance().monitorCountProcedure("insertXmlToDB"); statement = connection.prepareCall("{call insertXmlToDB(?)}"); connection.setAutoCommit(false); for (String xmlString : xmlCollection) { statement.setString(1, xmlString); statement.addBatch(); } // 执行批量,单独捕获批量更新异常 int[] executeResults; try { executeResults = statement.executeBatch(); } catch (BatchUpdateException e) { executeResults = e.getUpdateCounts(); // 可遍历执行结果统计失败数据,记录错误日志 for (int i = 0; i < executeResults.length; i++) { if (executeResults[i] == Statement.EXECUTE_FAILED) { System.err.println("第" + i + "条数据插入失败,对应xml内容:" + xmlCollection.get(i)); } } } connection.commit(); System.out.println("批量执行完成,共处理" + xmlCollection.size() + "条数据"); } catch (Exception ex) { ex.printStackTrace(); System.err.println("insertXmlToDB全局错误 : " + ex.getMessage()); // 仅全局异常触发全量回滚,单条批量异常不回滚成功数据 if (connection != null) { try { connection.rollback(); } catch (SQLException e) { e.printStackTrace(); } } } finally { if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } if (connection != null) { try { connection.setAutoCommit(true); connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
3. MySQL存储过程改造
在存储过程内部添加异常捕获逻辑,捕获单条数据插入的SQL异常后继续执行,不向外抛出异常中断批量流程,参考结构如下:
DELIMITER // CREATE PROCEDURE insertXmlToDB(IN xml_content TEXT) BEGIN -- 声明SQL异常捕获器,遇到异常时继续执行,不向外抛出 DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN -- 可选:插入错误日志表记录失败的xml内容和错误信息,方便后续排查 INSERT INTO xml_insert_error_log(content, error_msg, create_time) VALUES (xml_content, '数据插入异常', NOW()); END; -- 此处保留你原有插入业务逻辑 INSERT INTO your_target_table(xml_column) VALUES (xml_content); END // DELIMITER ;
如果不需要记录错误日志,仅保留DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END;即可实现异常自动跳过。
内容的提问来源于stack exchange,提问作者sajith kannan
相关产品推荐
相关产品推荐

