java - Hibernate 事务的内存影响

标签 java hibernate memory jax-rs spring-transactions

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

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

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

现在我的问题是关于hibernate的内存管理。由于真正的提交是在最后完成的(在使用实体管理器将所有元素持久化到数据库之后),hibernate 是否始终将数据真正提交到内存中?如果是这样,我对文件夹中文件的流式传输有任何优势,还是它完全没用,因为在提交给数据库之前,Spring 事务无论如何都将所有元素保存在内存中?

最佳答案

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

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

交易 tx = session.beginTransaction();

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

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

关于java - Hibernate 事务的内存影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20609256/

相关文章:

mysql - hibernate 、JPA、MySQL : Unable to build EntityManagerFactory

java - Hibernate Envers仅使用servlet保存用户名

android - 公共(public)或私有(private),Android变量真的很重要吗

c - #include 会增加 RAM 使用吗?

java - 使用 Mockito 进行 API stub 负载测试

java - 如何防止多次触发联系人监听器?

java - 定义动态单元格范围

java - 检查 Gemfire 缓存中对象的大小

hibernate - GORM协会解释

c - 如果堆栈变量被 malloc 重新分配,会发生什么情况?