Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 批处理执行失败后,如何重试未执行的语句?_Java_Postgresql_Prepared Statement - Fatal编程技术网

Java 批处理执行失败后,如何重试未执行的语句?

Java 批处理执行失败后,如何重试未执行的语句?,java,postgresql,prepared-statement,Java,Postgresql,Prepared Statement,我需要用CSV中的数据更新表。所有数据在更新发生之前都经过验证:验证方法(以下未显示)检查某些假设是否正确,并将对象“标记”为有效或无效。我已经对它进行了很多测试,它的工作完全符合我的要求 即便如此,我还是要保证,即使批处理失败,所有语句都会被执行,这是我无法想象的。如果发生这种情况,我希望跳过该fail语句中的批处理,并执行下一个批处理 public void updateTable(List<PersonBean> personList) { Connection co

我需要用CSV中的数据更新表。所有数据在更新发生之前都经过验证:验证方法(以下未显示)检查某些假设是否正确,并将对象“标记”为有效或无效。我已经对它进行了很多测试,它的工作完全符合我的要求

即便如此,我还是要保证,即使批处理失败,所有语句都会被执行,这是我无法想象的。如果发生这种情况,我希望跳过该fail语句中的批处理,并执行下一个批处理

public void updateTable(List<PersonBean> personList) {

    Connection connection = null;
    PreparedStatement ps = null;

    String updateDBPersonSQL = "UPDATE Person set merge_parent_id = ? WHERE id = ?";

    try {
        logger.info("DATA UPDATING STARTED");

        input = new FileInputStream("resources/propertiesFiles/applications.properties");
        properties.load(input);

        final int batchSize = Integer.parseInt(properties.getProperty("batchSize"));

        connection = DBConnection.getConnection();
        connection.setAutoCommit(false);

        int validObj = 0;

        ps = connection.prepareStatement(updateDBPersonSQL);

        for (int i = 0; i < personList.size(); i++) {

            PersonBean person = personList.get(i);

            if (person.getValidationStatus().equals("valid")) {

                ps.setInt(1, person.getMerge_parent_id());
                ps.setInt(2, person.getId());
                ps.addBatch();

                validObj++;

                if (validObj % batchSize == 0 && validObj != 0) {
                    ps.executeBatch();
                    connection.commit();

                    logger.info((batchSize) + " rows updated");
                } 
            }
        }
        int [] batchCount = ps.executeBatch();
        connection.commit();

        logger.info(batchCount.length + " rows updated");

        writeValidationStatusToCSV(personList);

    } catch (BatchUpdateException e) {
        int [] updateCount = e.getUpdateCounts();

            for (int i = 0; i < updateCount.length; i++) {

                if (updateCount[i] >= 0) {

                    logger.info(updateCount.length + " objects updated.");

                } else if (updateCount[i] == Statement.EXECUTE_FAILED) {

                    ?????
                }
            }
        logger.error(updateCount.length);
        logger.error("BatchUpdateException: " + e);
        logger.error("getNextException: " + e.getNextException());

        try {
            connection.rollback();
        } catch (SQLException e1) {
            logger.error("Rollback error: " + e1, e1);
        }
    } finally {
        if (ps!= null) {
            try {
                ps.close();
            } catch (SQLException e) {
                logger.info(e);
            }
        }
    }
    logger.info("DATA UPDATING FINISHED");
}
public void updateTable(列表个人列表){
连接=空;
PreparedStatement ps=null;
String updateDBPersonSQL=“更新人员集合并\u父项\u id=?其中id=?”;
试一试{
logger.info(“数据更新已启动”);
输入=新文件输入流(“资源/属性文件/应用程序.properties”);
属性。加载(输入);
final int batchSize=Integer.parseInt(properties.getProperty(“batchSize”);
connection=DBConnection.getConnection();
connection.setAutoCommit(false);
int-validObj=0;
ps=connection.prepareStatement(updateDBPersonSQL);
对于(int i=0;i=0){
info(updateCount.length+“objects updated.”);
}else if(updateCount[i]==语句。执行\u失败){
?????
}
}
logger.error(updateCount.length);
logger.error(“BatchUpdateException:+e”);
logger.error(“getNextException:+e.getNextException());
试一试{
connection.rollback();
}捕获(SQLException e1){
logger.error(“回滚错误:+e1,e1”);
}
}最后{
如果(ps!=null){
试一试{
ps.close();
}捕获(SQLE异常){
logger.info(e);
}
}
}
logger.info(“数据更新完成”);
}
我看到了很多关于如何处理异常的资料,但没有任何资料向我解释或指出如何重试下一个语句,这意味着如何执行下一批

我如何做到这一点


编辑:我正在使用Postgresql我通过使用
try
catch
语句围绕批处理执行来尝试下一批处理。这样我就能够捕获
BatchUpdateException
并调用
continue
语句

try {
ps.executeBatch();
connection.commit();
/*Some more code*/

} catch (BatchUpdateException e) {

connection.rollback();
/*Some more code*/

continue;
}
我还使用了一些控制逻辑来“标记”已经执行并记录的语句和批处理,以便在某些语句失败时更容易进行故障排除

以下是完整的代码:

public void updateTable(List<PersonBean> personList) throws Exception {

logger.info("TABLE UPDATE STARTED");

List <PersonBean> personListValidated = createValidStmtList(personList);

Connection connection = null;
PreparedStatement ps = null;

String updatePersonSQL = "UPDATE Person SET merge_parent_id = ? WHERE id = ?";

input = new FileInputStream("resources/propertiesFiles/applications.properties");
properties.load(input);

final int batchSize = Integer.parseInt(properties.getProperty("batchSize"));

/*A list was used to "flag" the batches that were already executed. BatchStatus objs have only two parameters, number (incremented as the batches are being executed) and status (success or fail).*/
List <BatchStatus> batchStatusList = new ArrayList<BatchStatus>();

 /*This variables will be used to help flag the batches and statements that were already executed.*/
int batchCount = 0;
int stmtAddedToBatchCount = 0;

try {
    connection = DBConnection.getConnection();
    connection.setAutoCommit(false);

    ps = connection.prepareStatement(updatePersonSQL);

    /*personListValidated contains the objects that will be updated in the table. Instead of doing the validation on the update method, I decomposed
     * this part in other 2 methods, making it easier to control of the statements added to the batch.
     */
    for (int i = 0; i < personListValidated.size(); i++) {

        PersonBean personValid = personListValidated.get(i);

        ps.setInt(1, personValid.getMerge_parent_id());
        ps.setInt(2, personValid.getId());
        ps.addBatch();

        personValid.setToBatch("true");

        stmtAddedToBatchCount++;

        logger.info("Row added to batch (count: " + stmtAddedToBatchCount + ")");

        if (stmtAddedToBatchCount % batchSize == 0) {
            batchCount++;

            try {
                ps.executeBatch();
                connection.commit();

                for (int j = stmtAddedToBatchCount - batchSize; j < stmtAddedToBatchCount; j++){

                    personValid = personListValidated.get(j);
                    personValid.setValidationStatus("success");
                }

                BatchStatus batchStatusObj = new BatchStatus(batchCount, "sucess");
                batchStatusList.add(batchStatusObj);   

                logger.info(batchStatusList.get(batchCount - 1));

            } catch (BatchUpdateException e) {

                connection.rollback();

                for (int j = stmtAddedToBatchCount - batchSize; j < stmtAddedToBatchCount; j++){

                    personValid = personListValidated.get(j);
                    personValid.setValidationStatus("fail");
                }

                BatchStatus batchStatusObj = new BatchStatus(batchCount, "fail");
                batchStatusList.add(batchStatusObj);

                logger.info(batchStatusList.get(batchCount - 1));
                logger.error("Bacth execution fail: " + e, e);

                continue;
            }
        }
    }

} catch (SQLException e) {
    logger.error(e, e);
}
int[] lastBatchCount = null;

/*Try and catch to handle the statements executed on the last batch*/
try {
    lastBatchCount = ps.executeBatch();
    connection.commit();

    for (int j = batchStatusList.size() * batchSize; j < stmtAddedToBatchCount; j++){

        PersonBean personValid = personListValidated.get(j);
        personValid.setValidationStatus("success");
    }

    logger.info(lastBatchCount.length + " rows inserted on the last batch");
    logger.info("Last batch excuted");

} catch (BatchUpdateException e) {

    connection.rollback();

    for (int j = batchStatusList.size() * batchSize; j < stmtAddedToBatchCount; j++){

        PersonBean personValid = personListValidated.get(j);
        personValid.setValidationStatus("fail");
    }

    logger.error("Last batch fail to execute: " + e, e);
}
writeValidationStatusToCSV(personList);

logger.info("TABLE UPDATE FINISHED");
public void updateTable(List personList)引发异常{
logger.info(“表更新已启动”);
List personListValidated=CreateValidsMTList(personList);
连接=空;
PreparedStatement ps=null;
String updatePersonSQL=“更新人员集合并\u父项\u id=?其中id=?”;
输入=新文件输入流(“资源/属性文件/应用程序.properties”);
属性。加载(输入);
final int batchSize=Integer.parseInt(properties.getProperty(“batchSize”);
/*一个列表用于“标记”已执行的批。BatchStatus OBJ只有两个参数,编号(随着批的执行而递增)和状态(成功或失败)*/
List batchStatusList=新建ArrayList();
/*此变量将用于帮助标记已执行的批处理和语句*/
int batchCount=0;
int stmtadedtobatchcount=0;
试一试{
connection=DBConnection.getConnection();
connection.setAutoCommit(false);
ps=connection.prepareStatement(updatePersonSQL);
/*personListValidated包含将在表中更新的对象
*这一部分在其他两种方法中进行了介绍,使添加到批处理中的语句更易于控制。
*/
对于(int i=0;i