hibernate interceptor所引发的有关问题
去年写的,都忘了发了,现在发出来。
最近在做Hibernate
Interceptor的实现时,因为不是所有的Dao都要使用interceptor,而且配置的时候,我们使用了冗于多个
SessionFactory,使用Spring的配置继承方法继承原始Session
Factory的所有配置,并加入entityInterceptor的配置做到对hibernate制作的拦截。这时,我们就出现了,两个比较大的问
题。
因为冗于了多个的sessionFactory,而sessionFactory是一个重量级的对象,加上,我们在hibernate中配置了非常多的实
体对象,这样,每一次启动服务器的时候,都会造成多个spring
新增多个sessionFactory的情况,造成了内存的暴涨,从而就倒至了出现服务器内存溢出的情况。在这里,因为自己本身在以前的项目中的项目比较
小,所以新增一个sessionFactory不会有太大的内存消耗,但在大项目里,这个内存的消耗就很大,我根本就没有意识到这个,从而倒至了这个问题
的发生。
因为有不同的Dao,每一个Dao的SessionFactory配的可能是不同的,这样,在同一个事务中,就有可能出现两个以上的
SessionFactory的情况。这时,如果一对有外键关系的主从表出表在两个不同sessionFactory
的Dao的情况下,不会按代码的顺序执行的情况,会出现没有parent
key的情况,也就是出现了,先执行子表的Sql再执行主表的。因为,在spring容器中,他使用的localthread来做hibernate
session的保存地,也就是在同一个线程下,一个SessionFactory只可能出现一个session,他从
SessionFactoryUtils.getSession()默认每一次都会去SessionFactory中看一个,这个
sessionFactory是否有保存一个session,如果有那就使用这个session,如果没有如果允许创建一个新的session,那就创建
一个并发入到localthread中去。当事务结束后,spring会依次去提交session,从就倒至了没有按照代码顺序去执行的情况。
这两个问题中,都是因为,在一个应用中同时出现多个session
Factory而产生的,解决的方法,当然是尽量在一个应用中配制多个sessionFactory,如果有出现了一个事务中,有多个
sessionFactory的情况,如果要保证sql语句按你的代码的顺序去执行,你就不要去使用spring容器。
------------------------------------------------------
前天,又测出问题来了,在集成测试环境中,业务数据,因为新增session
Factory而不能提交,我在本机试了多次,但都可以,不知是不是出现了环境问题。不过,根据,对spring源码的分析,我的确看到了不提交的可能
性。因为在spring容器的事务配置中,使用hibernateTrasactionMangment这个事务管理器来做事务控制。而这个事务管理器他
只能对一个sessionFactory进行提交,虽然在local
thread中有两个session,但事务管理器只会把给自己配置的那个sessionFactory产生的session做提交,从而出现了业务数据
没有提交的情况。
这种情况有两种解决方法,那就是使用jta事务,spring对jta事务有处理这种情况的能力,但是,不是每个地方可以使用jta。还有一种方法是写一个自定义的事务管理器,但,这个要花几天的时间进行编写测试。所以也不能成形。
最后,用了最土的方法,在主的sessionFactory注入interceptor,这样对每一个BO进行拦截,这就免去了多个
sessionFactory的情况。