内存对Hibernate事务的影响

时间:2013-12-16 11:00:01

标签: java hibernate memory jax-rs spring-transactions

我正在开发一个JAX-RS Web应用程序,它将完整的文件夹内容读入数据库。该文件夹中的文件可能非常大(+ -100Mb)。 JAXB用于将xml解组为Java对象。这些对象使用Hibernate持久保存到DB中。

为避免对内存造成影响,我决定不将整个文件的内容保留在内存中,而是使用流式处理单独处理每个对象。

另一个要求是以事务方式处理文件夹。因此,如果其中一个xmls发生错误,则将完整的文件夹内容移动到错误文件夹,并且已经回滚已添加到数据库的元素。

现在我的问题与hibernate的内存管理有关。由于真正的提交是在最后完成的(在使用实体管理器将所有元素持久化到数据库之后),hibernate是否一直保持数据在内存中真正提交?如果是这样,我对文件夹中的文件流有什么好处,还是完全无用,因为在提交到数据库之前,Spring事务无论如何都将所有元素都保存在内存中?

1 个答案:

答案 0 :(得分:2)

如果你想在Hibernate中以这种方式传输,你可以做几件事。

  • 定期清除会话缓存。您可以先清除内存缓存的内容,先将其刷新到数据库,然后清除它们。要记住的一件事是,一旦你从第一级缓存中清除了某些东西,就不能再使用它了(例如,你不能持久存在一个对象,清除它,然后将该对象添加到一个对象中。 - 稍后协会)。这是一个每次都清除缓存的简单示例。这有点太简单了,实际上你可能想要每50个左右的项目清除缓存,这样你就不会刷新每一条记录(可能会成为性能问题)。

Transaction tx = session.beginTransaction();

try {
    while(...) {
        processNextRecord(session);
        session.flush();
        session.clear();
    }
    tx.commit();
} catch (Exception ex) {
    tx.rollback();
} 
  • 使用无状态会话。 Hibernate中的StatelessSession对象允许您以类似于Session接口的方式操作数据库(持久化,修改,删除实体等)但稍微不同。例如,级联不受尊重,您必须明确调用更新等。好处是无状态会话不会在内存中存储任何内容。

有关所有这些的详细说明,请查看Hibernate在batch processing上的文档。