如何有效地在Hibernate中进行批量更新

Sah*_*wal 8 java postgresql hibernate jdbc batch-processing

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

其中一个是使用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);
Run Code Online (Sandbox Code Playgroud)

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

我们必须只进行批量更新是可以的.

但是我有以下问题退出:

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

那么,我们应该如何处理这个案子呢?

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

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

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

Pri*_*ngh 1

你的意思是这样说:

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

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

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