【问题标题】:How to persist a block of objects in the database by using multithreading but in an order? [duplicate]如何通过使用多线程但按顺序将对象块保存在数据库中? [复制]
【发布时间】:2015-04-17 14:53:47
【问题描述】:

我正在使用 Hibernate、Maven 项目和 JBoss AS7。我有一个选择请求,它给了我一个对象列表(假设我有例如 100000 个客户),我想将它们保存在一个新表中。如果我尝试直接这样做,那么我使用的 JBoss 服务器会给我一个著名的错误:timeout

我正在考虑是否可以通过使用多线程来做到这一点。

...
entityManager.getTransaction().begin();
  for(Client client:ListClients{
    entityManager.persist(client);
   }
    entityManager.getTransaction().commit();
...

【问题讨论】:

  • 您是否考虑过因为超时而保留较小的数据块而不是引入多线程?
  • 当我尝试持久化很多客户端(我不知道数字)但在我的数据库中我有超过 25000000 个客户端,因此选择并将其持久化到另一个表将需要很多时间时间和服务器将显示错误消息:超时,这就是为什么我认为逐块保留客户端将解决该问题。其他人认为,在相同的情况下,我也使用原生查询
  • 如果这是必须立即执行并且不能在晚上作为批处理运行的事情,您应该重新考虑您的应用程序的设计。当然我不了解你的系统,但也许有一种方法可以让你不必将这么多数据写入新表。
  • in order 的意思是 serial 正好是并发的相反,那你为什么要使用多线程然后将所有内容都以单线程的方式 serial 再次显示充其量是根本缺乏理解

标签: java multithreading hibernate


【解决方案1】:

多线程在这里是错误的方向,如果您希望插入以特定顺序发生,则更是如此。您可以以 1000 个左右的块处理您的实体,分别提交每个块,并定期刷新或使用无状态 Hibernate 会话,以降低第一级缓存大小。 Hibernate 文档有一个chapter on batch processing

如果这是已经在数据库中的数据,那么使用直接在数据库上运行的存储过程或脚本执行此操作可能会好得多。要将数据导入数据库,请查看数据库附带的批量复制工具并改用它。批量复制工具可以暂时放弃数据库约束,暂停重建索引,而且网络协议不像JDBC那样啰嗦,会快很多。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-22
    • 2021-11-06
    相关资源
    最近更新 更多