如果发生异常(SQLException | BatchUpdateException)-Java

时间:2020-07-20 15:29:58

标签: java jdbc prepared-statement sqlexception

我遇到了这样的情况,我的代码在某些事务中受到SQL Server的死锁问题的打击。因此,我实施了重试逻辑来克服相同的问题。现在,我面临一个新问题。问题是,每当重试时,从异常中恢复后,尝试执行的批处理将为空/清除。这导致丢失数据插入/更新。请帮助我。

摘要: 如果发生异常(SQLException | BatchUpdateException),请重试preparestatement批处理

当前实施:

do {
        try {
            if (isInsert) {
                int[] insertRows = psInsert.executeBatch();
                psInsert.clearBatch();
                System.out.println("insertRowsSuccess:" + Arrays.toString(insertRows));
            } else {
                int[] updateRows = psUpdate.executeBatch();
                psUpdate.clearBatch();
                System.out.println("updateRowsSuccess:" + Arrays.toString(updateRows));
            }
            break;
        } catch (BatchUpdateException e) {
            conn.rollback();
            if (++count == maxTries) {
                System.out.println(e.getMessage());
                getFailedRecords(e, operation);
            }
        } catch (SQLException e) {
            if (++count == maxTries) {
                System.err.format("SQL State: %s\n%s", e.getSQLState(), e.getMessage());
            }
        }
        System.out.println("Tries:" + count);
    } while (true);
    

private static void getFailedRecords(BatchUpdateException ex, String operation) {

    int[] updateCount = ex.getUpdateCounts();
    ArrayList<Integer> failedRecsList = new ArrayList<Integer>();
    int failCount = 0;

    for (int i = 0; i < updateCount.length; i++) {
        if (updateCount[i] == Statement.EXECUTE_FAILED) {
            failCount++;
            failedRecsList.add(i);
        }

    }

    System.out.println(operation + " Failed Count: " + failCount);
    System.out.println(operation + " FailedRecordsIndex:" + failedRecsList);

}       

2 个答案:

答案 0 :(得分:0)

我认为您应该将clearBatch()移到try之外。如果您必须重新检查它是插入还是更新,就这样吧。如果psInsertpsUdate是同一类,或者是从同一基类派生的(听起来像它们应该如此),则可以轻松地在一个单独的线性方法中调用它。

我还认为,如果您将此问题提交给code review,则会得到一些改进代码的好的建议。我并不是说这很糟糕,但我认为基础模型仍有改进的空间。不过,我对Java还不够熟悉。

答案 1 :(得分:0)

执行后,无论批次成功与否,都将清除该批次。重试之前,您需要重新填充批次。