You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 15:45:02