2013-12-16 49 views
1

我正在研究将完整文件夹内容读入数据库的JAX-RS Web应用程序。该文件夹中的文件可能很大(+ -100Mb)。 JAXB用于将xml解组到Java对象中。这些对象使用Hibernate持久化到数据库中。休眠事务对内存的影响

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

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

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

回答

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接口但稍有不同的方式操纵数据库(持久,修改,删除实体等)。例如,级联不受尊重,你必须明确地调用更新等。好处在于无状态会话不会在内存中存储任何内容。

有关所有这些的详细解释,请参阅batch processing上的更多Hibernate文档。