【问题标题】:How to DO Batch Update in Hibernate Effectively如何有效地在 Hibernate 中进行批量更新
【发布时间】:2018-04-09 05:22:46
【问题描述】:

我阅读了很多文章并找到了一些批处理的方法

其中之一是使用 flush 和 clear ,以下是代码

        long t1 = System.currentTimeMillis();
        Session session = getSession();
        Transaction transaction = session.beginTransaction();
        try {
            Query query = session.createQuery("FROM PersonEntity WHERE id > " + lastMaxId + " ORDER BY id");
            query.setMaxResults(1000);
            rows = query.list();
            int count = 0;
            if (rows == null || rows.size() == 0) {
                return;
            }
            LOGGER.info("fetched {} rows from db", rows.size());
            for (Object row : rows) {
                PersonEntity personEntity = (PersonEntity) row;
                personEntity.setName(randomAlphaNumeric(30));
                lastMaxId = personEntity.getId();
                session.saveOrUpdate(personEntity);
                if (++count % 50 == 0) {
                    session.flush();
                    session.clear();
                    LOGGER.info("Flushed and Cleared");
                }
            }
        } finally {
            if (session != null && session.isOpen()) {
                LOGGER.info("Closing Session and commiting transaction");
                transaction.commit();
                session.close();
            }
        }
        long t2 = System.currentTimeMillis();
        LOGGER.info("time taken {}s", (t2 - t1) / 1000);

在上面的代码中,我们批量处理 1000 条记录并在同一个事务中更新它们。

只需要批量更新就可以了。

但我有以下问题:

  1. 可能会有其他线程 (T2) 为某些运行时更新操作访问同一行集的情况,但在这种情况下,直到 1000 批不会被提交,T2 remians 卡住了

那么,我们应该如何处理这种情况呢?

我可能的想法/解决方案:

  1. 我认为我们可以在不同的会话中进行更新,例如 50 个小批量
  2. 对更新使用不同的无状态连接并逐个提交事务,但在一批 1000 完成时关闭会话。

请帮助我获得更好的解决方案。

【问题讨论】:

  • 您能否说明您需要对这些实体进行什么样的更新,以及为什么您不想或不能对其使用 SQL 或 HQL?例如docs.jboss.org/hibernate/orm/3.3/reference/en/html/…
  • 如果您有两个事务处理相同的数据,您预计会发生什么?
  • 假设我们有票务系统,并且有一个 TimerTsk 定期读取和批量更新。现在假设一些工单也更新了,现在第二个操作会卡住一段时间,如果及时任务,这一行将出现在当前批次中。
  • 是的,数据库就是这样工作的。
  • 是的,这就是我要问的原因,有没有更好的方法可以最大限度地减少这种滞后

标签: java postgresql hibernate jdbc batch-processing


【解决方案1】:

你的意思是这样的:

  1. 事务中正在进行批量更新

  2. 与此同时,另一个线程也开始更新批处理中的一条记录

  3. 因此,批处理将等待第 2 点中的更新完成。这会导致批处理中的其余记录也等待。 到目前为止,一切似乎都很好。然而,这里重要的一点是事务的完成是为了“更快”地更新大量记录。通常,事务用于确保“一致性/原子性”。 如何设计这件作品 - 一次快速更新多条记录,原子性不是主要标准,而另一个线程也可能要求更新批处理中的记录

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-08
    • 2016-08-15
    • 1970-01-01
    • 2018-11-05
    • 2018-04-01
    • 2020-07-10
    相关资源
    最近更新 更多