【问题标题】:How to handle bad or duplicate records in Statement.ExecuteBatch()如何处理 Statement.ExecuteBatch() 中的错误或重复记录
【发布时间】:2014-07-28 04:55:09
【问题描述】:

我有一个 java 程序,它处理一个包含 100 万条记录的文件,并使用批量插入将其插入到表中,即在每 1000 条记录之后使用Statement.addbatch()Statement.executeBatch()。程序运行得很快。

但是,如果存在重复记录,即表引发异常,则整个批次都将消失,其余记录将无法跟踪。

即使我得到 updatecount() 也无济于事,因为我无法将重复项插入另一个表等。

有没有一种方法,在 1000 个特定的批次插入中,如果有坏记录,那么该批次中的每条记录都可以一个一个地处理,以便可以将坏/重复记录放在另一个表中,并且常规表中的非重复项?

还有其他我可以使用的课程吗?我知道在 C++ 中,Oracle 提供 OCI 可以处理批处理中的单个记录(称为主机数组操作),但在 Java 中,批量插入通常由循环中的Statement.adding 完成,然后使用Statement.executeBatch() 插入。

谢谢。

【问题讨论】:

  • 您可以在批处理旁边的某个容器中收集这 1000 个值,如果批处理失败,您自己一个一个运行它们,不是吗?如果批处理成功,则清除容器并进入下一个 1000

标签: java prepared-statement ojdbc batch-insert


【解决方案1】:

我会把它分成 1000 个的小块,像这样

  final int BATCH_SIZE = 1000;
  for (int i = 0; i < DATA_SIZE; i++) {
   statement.setString(1, "a@a.com");
   statement.setLong(2, 1);
   statement.addBatch();
   if (i % BATCH_SIZE == BATCH_SIZE - 1)
   statement.executeBatch();
  }
  if (DATA_SIZE % BATCH_SIZE != 0)
  statement.executeBatch();

一批记录很少包含坏记录是很常见的。如果您尝试一次性插入所有记录,并且一条记录失败,则整个插入将被拒绝。这是意料之中的,也是“事务处理”的核心目的。

通常对于批量插入,您可以采取两种方法:

1) 每次插入记录后提交 --> 非常耗费性能的过程。

2) 将总记录分成更小的“块”并插入数据库。这样只有包含坏记录的块会失败,而其他块将被插入到数据库中。

或者,如果您不想自己处理这些事情,请选择框架。 Spring batch

在这种情况下可能是您的选择之一

【讨论】:

  • 您在每次插入后执行批处理正确吗?那么这一切的目的是什么?其次,如果我有小块,然后如果一条记录失败,那么我仍然会丢失一些记录。要求是不得丢失任何记录。每条记录都必须转到表中,或者重复记录的辅助表。
猜你喜欢
  • 1970-01-01
  • 2017-10-22
  • 2015-04-30
  • 1970-01-01
  • 1970-01-01
  • 2023-01-09
  • 2011-05-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多