gpt4 book ai didi

java - 如何在postgreSql中使用JDBCTemplate batchUpdate捕获错误记录?

转载 作者:行者123 更新时间:2023-12-05 04:55:07 27 4
gpt4 key购买 nike

我正在使用 Spring JDBCTemplate 和 BatchPreparedStatementSetter 在 postgreSql 数据库上执行批量更新。我想捕获错误的记录,在浏览了一些帖子后,发现捕获 BatchUpdateException 然后查找“Statement.EXECUTE_FAILED”可以帮助我识别错误的记录。但是,当我按如下方式实现它时,我从未收到 batchUpdate 异常。

在这里,我试图重复输入相同的 ID“120”,以便我获得唯一的约束违规,从而在数据库级别强制引发异常。

@Override
@Transactional
public void batchInsertTenantPayloads(List<Payload> payloadMessages) {

try {
jdbcTemplate.batchUpdate(DBQueryConstants.INSERT_INTO_MESSAGE_METERING_PAYLOAD, new BatchPreparedStatementSetter() {

@Override
public int getBatchSize() {
return payloadMessages.size();
}

@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {

ps.setLong(1, 120);
ps.setString(2, payloadMessages.get(i).getId());
ps.setDate(3, Date.valueOf(payloadMessages.get(i).getTs().toLocalDate()));
ps.setString(4, payloadMessages.get(i).getContent().getId());
ps.setInt(5, payloadMessages.get(i).getStatus().ordinal());
ps.setString(6, MyUtils.toJSON(payloadMessages.get(i)));
}
});

} catch (Exception e) {
if (e.getCause() instanceof BatchUpdateException) {
LOGGER.info("Batch exception occurred");
BatchUpdateException be = (BatchUpdateException) e.getCause();
int[] batchUpdateCounts = be.getUpdateCounts();
for (int index = 0; index < batchUpdateCounts.length; index++) {
if (batchUpdateCounts[index] == Statement.EXECUTE_FAILED) {
LOGGER.error(
"[MMC] batch update Error execution >>>>>>>>>>>" + index + " --- , codeFail : " + batchUpdateCounts[index]
+ "---, line " + payloadMessages.get(index));
}
}

}

}

}

挑战在于我从未进入 BatchUpdateException block 。相反,我得到了一个

org.springframework.dao.DuplicateKeyException

嵌套异常是

org.postgresql.util.PSQLException: ERROR: duplicate key value violatesunique constraint "message_metering_payload_pkey"

我可以做些什么不同的事情来捕获 batchUpdate 异常并只获取错误行并提交正确的行。

我的批量大小是 500。Postgre 版本是 9.6,我使用的是 spring 2.0 和 spring jdbc 5.1.3。

堆栈跟踪看起来像这样

org.springframework.dao.DuplicateKeyException: PreparedStatementCallback; SQL [insert into message_metering_payload(id,tenant_name,source_dt,exchange_id,status,payload)values(?,?,?,?,?,?)]; ERROR: duplicate key value violates unique constraint "message_metering_payload_pkey"
Detail: Key (id)=(120) already exists.; nested exception is org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "message_metering_payload_pkey"
Detail: Key (id)=(120) already exists.
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:242)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
at org.springframework.jdbc.core.JdbcTemplate.translateException(JdbcTemplate.java:1444)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:632)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:646)
at org.springframework.jdbc.core.JdbcTemplate.batchUpdate(JdbcTemplate.java:936)

最佳答案

您不会得到 BatchUpdateException,因为您可能会使用 SQLErrorCodeSQLExceptionTranslatorjdbcTemplate 中,它处理 BatchUpdateException in a special way :

if (sqlEx instanceof BatchUpdateException && sqlEx.getNextException() != null) {
SQLException nestedSqlEx = sqlEx.getNextException();
if (nestedSqlEx.getErrorCode() > 0 || nestedSqlEx.getSQLState() != null) {
sqlEx = nestedSqlEx;
}
}

有一个问题:

如果您使用 SQLStateSQLExceptionTranslator,您可以缓解这种情况:

jdbcTemplate.setExceptionTranslator(new SQLStateSQLExceptionTranslator());

然后您将得到 BatchUpdateException 作为 原因:

try {
// ...
} catch (DataAccessException e) {
Throwable cause = e.getCause();
logger.info("cause instanceof BatchUpdateException = {}", cause instanceof BatchUpdateException);
}

但是请注意,对于 postgresql jdbc 驱动程序,BatchUpdateException#getUpdateCounts() 将包含 EXECUTE_FAILED只是,尽管可以成功插入一些行。

参见 this问题

关于java - 如何在postgreSql中使用JDBCTemplate batchUpdate捕获错误记录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65561067/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com