Hibernate 处理 大数据量的只读数据
知识准备:
FlushMode 为下列四种值的时候的刷新策略
flush mode就是hibernate session采取什么样的数据刷新的策略。

问题
我们知道,Hibernate会把查询过的对象缓存起来什么,hibernate会记录session生命周期内所有缓存对象的操作过程,最后都会反映到数据库去。
这都归结于Hibernate的脏检查(dirty checking)。
每次装载一个对象到内存时,session始终跟踪它的修改。
于是每次对数据的查询,session都将迭代所有的session中的对象并检查脏数据,将脏数据flush到数据库。
Hibernate这样做的良苦用心是为了确保在执行查询之前所有可能影响查询的变化都被提交到数据库。
这对零星数据量的应用来讲,不足为道。
但面对数千个对象和千余次的查询来讲,性能消耗很大。
处理
session.setFlushMode(FlushMode.MANUAL)
FlushMode.MANUAL状态下,查询时不进行脏检查,省去大量消耗。
但 ,一定要保证 查询出的数据不会被修改,只做只读处理。
以前用FlushMode.NEVER 已经废弃了,被MANUAL取代。
具体代码如下:
hibernate
FlushMode previous = session.getFlushMode();
session.flush(); // who know's what been done till now
session.setFlushMode(FlushMode.MANUAL);
// Do some querying
// Do some more querying
// Really load up that session
// Execute a few more queries
// Write back to some tables
// 最后,把不需要写入数据库的数据都 evict 或 clear 掉,防止 flush的时候 浪费时间让session中的缓存数据去与 快照 去比对
session.flush();
session.setFlushMode(previous);
JPA
FlushModeType previous = em.getFlushMode(); try{ em.flush(); em.setFlushMode(FlushModeType.COMMIT); // Do some querying // Do some more querying // Really load up that session // Execute a few more queries // Write back to some tables // 最后,把不需要写入数据库的数据都 evict 或 clear 掉,防止 flush的时候 浪费时间让session中的缓存数据去与 快照 去比对 em.flush(); }finally { em.setFlushMode(previous); }
session.evict(obj):会把指定的缓冲对象进行清除;
session.clear():把缓冲区内的全部对象清除,但不包括操作中的对象。
如果启用了二级缓存,从机制上讲Hibernate为了维护二级缓存,我们在做插入、更新、删除操作时,Hibernate都会往二级缓存充入相应的数据。
性能上就会有很大损失,建议在批处理情况下禁用二级缓存。
感觉还有一种方式可以解决,不过没真正用过:
hibernateStatelessSession (无状态session)接口
浙公网安备 33010602011771号