非web系统中解决hibernate的Nosession问题

在使用hibernate时,经常会遇到Nosession问题,spring提供延长session生成周期的解决方案,分别可以使用OpenSessionInViewFilter和OpenSessionInViewInterceptor两种方案,一种是过滤器实现的,一种是拦截器实现的;其中过滤器配置到web.xml中;拦截器配置到spring的applicationContext中,但是这两种方案都适合在web系统中使用。

出现问题的背景:在使用公司的后台系统数据维护引擎时,需要开发维护实例,维护实例是数据库业务表对应的原子化操作的实例,工作流程是:查询源数据-->组装为历史表数据à保存源数据到历史表,删除源数据。使用的实体类配置的是lazy懒加载,当维护引擎查询到源数据后,实例对源数据进行业务处理,当操作子类时出现Nosession问题。

解决思路1:查询时自主open一个session,将session绑定到threadlocal中,维护方法结束,去threadlocal中获取session并关闭。在操作子类时,Nosession问题解决,但是在保存历史表删除源数据时,hibernate抛出同一个连接出现两个session是非法的,原因是使用spring的声明式事务时,spring会为save方法新启一个session,这时就出现了两个session。

解决思路2:为解决1中出现两个session的问题,将HibernateTemplate中的doExecute方法进行改造,将新启的session不关闭,而是绑定到TransactionSynchronizationManager事务管理器中,由spring的事务管理器去管理,此时需要将spring的事务传播特性由REQUIRES_NEW改为REQUIRES。两个session的问题解决了。又出现第二个问题,当查询不到数据时,就不会save历史数据,此时不会触发spring的事务管理器,spring的事务管理器在提交事务或回滚事务后才会调用doCleanupAfterCompletion方法去清除session。此时session不会被关闭,连接不会释放,一小会就连接占满。

解决思路3:结合第一和第二,两种方法,将开启的session放到threadlocal中,在HibernateTemplate的doExecute方法中,当getCurrentSession()获取到session时,将threadlocal中session关闭,并且在方法结束再去threadlocal中查看session是否还存在,如果存在再将其关闭。暂时解决了问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值