`
qingcyangg
  • 浏览: 14701 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

在使用spring时候的小问题

阅读更多
由于业务上的变化,要让我们正在开发的模块独立出来单独作为一个应用。OK,由于自己是刚毕业的对于系统的搭建工作肯定是不会要我做了,呵呵。在应用搭建完成之后,OK,下面就是我的编码工作了。我将自己写的代码搬过来之后,调试开始,怪了,为什么在拿用户表里数据的时候老是抛EXCEPTION,当时以为自己的程序逻辑有问题,但是通过检查,断点调试跟踪,发现在DAO层出现了问题。反复查看,最会发现是他们在搭建的时候将web.xml中的一个配置文件给注释掉了,晕了。
<filter>
<filter-name>openSessionInViewFilter</filter-name>
<filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
</filter-class>
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
</filter>

以下是自己在通过这次问题之后去网上查看收集的一下关于opensessioninview的相关资料。
OpenSessionInViewFilter是Spring提供的一个针对Hibernate的一个支持类,其主要意思是在发起一个页面请求时打开 Hibernate的Session,一直保持这个Session,直到这个请求结束,具体是通过一个Filter来实现的。

由于Hibernate引入了Lazy Load特性,使得脱离Hibernate的Session周期的对象如果再想通过getter方法取到其关联对象的值,Hibernate会抛出一个 LazyLoad的Exception。所以为了解决这个问题,Spring引入了这个Filter,使得Hibernate的Session的生命周期变长。 注意,在这里有个2个Tips:
1)通过getSession()获得的这个Session做了一次
session.setFlushMode(FlushMode.NEVER); 有关FlushMode可以参考一下这篇文章。http://www2.matrix.org.cn/resource/article/2006-10-08/Hibernate+FlushMode+NEVER_312bca85-5699-11db-91a0-d98dff0aec60.html
2)Spring对拿到的Session做了一次绑定到当前线程的做法,使得这个Session是线程安全的。

从上述代码其实可以得到一些对我们的开发有帮助的结论:
1)如果使用了OpenSessionInView模式,那么Spring会帮助你管理Session的开和关,从而你在你的DAO中通过HibernateDaoSupport拿到的getSession()方法,都是绑定到当前线程的线程安全的Session,即拿即用,最后会由Filter统一关闭。
2)由于拿到的Hibernate的Session被设置了session.setFlushMode(FlushMode.NEVER); 所以,除非你直接调用session.flush(),否则Hibernate session无论何时也不会flush任何的状态变化到数据库。因此,数据库事务的配置非常重要。(我们知道,在调用 org.hibernate.Transaction.commit()的时候会触发session.flush())我曾经见过很多人在使用OpenSessionInView模式时,都因为没有正确配置事务,导致了底层会抛出有关FlushMode.NEVER的异常。

OpenSessionInView这个模式使用比较简单,也成为了大家在Web开发中经常使用的方法,不过它有时候会带来一些意想不到的问题,这也是在开发中需要注意的。
1. 在Struts+Spring+Hibernate环境中,由于配置的问题导致的模式失效
这个问题以前论坛曾经讨论过,可以参考一下下面这个帖子:
http://www.iteye.com/topic/15057

2. OpenSessionInView的效率问题
这个问题也有人在论坛提出过,Robbin曾经做过具体的测试,可以具体参考一下下面这个帖子:
http://www.iteye.com/topic/17501

3. 由于使用了OpenSessionInView模式后造成了内存和数据库连接问题
这个问题是我在生产环境中碰到的一个问题。由于使用了OpenSessionInView模式,Session的生命周期变得非常长。虽然解决了Lazy Load的问题,但是带来的问题就是Hibernate的一级缓存,也就是Session级别的缓存的生命周期会变得非常长,那么如果你在你的 Service层做大批量的数据操作时,其实这些数据会在缓存中保留一份,这是非常耗费内存的。还有一个数据库连接的问题,存在的原因在于由于数据库的 Connection是和Session绑在一起的,所以,Connection也会得不到及时的释放。因而当系统出现业务非常繁忙,而计算量又非常大的时候,往往数据连接池的连接数会不够。这个问题我至今非常头痛,因为有很多客户对数据连接池的数量会有限制,不会给你无限制的增加下去。

4. 使用了OpenSessionInView模式以后取数据的事务问题
在使用了OpenSessionInView以后,其实事务的生命周期比Session的生命周期来得短,就以为着,其实有相当一部分的查询是不被纳入到事务的范围内的,此时是否会读到脏数据?这个问题我至今不敢确认,有经验的朋友请指教一下。

最后提一下OpenSessionInView模式的一些替代方案,可以使用 OpenSessionInViewInterceptor来代替这个Filter,此时可以使用Spring的AOP配置,将这个 Interceptor配置到你所需要的层次上去。另外就是只能使用最古老的Hibernate.initialize()方法进行初始化了。
分享到:
评论

相关推荐

    在SpringCloud 使用Security+Oauth2 时候再去使用fegin,发现出现401未授权

    我们在使用spring cloud时如果设置了oauth2授权模式,那么应用服务A再调用服务B时使用Feign请求会出现401授权认证的问题,那么解决办法就是在feign调用请求时获取到assessToken并设置到请求header中就可以解决这个...

    spring cloud 使用Zuul 实现API网关服务问题

    在本文中,我们将主要介绍如何使用 Spring Cloud 的 Zuul 组件来实现 API 网关服务问题。 Zuul 是一个基于 Netflix Zuul 的 API 网关组件,它可以解决路由规则和服务实例的维护问题,以及一些校验(比如登录校验等)...

    最简单的用户登录与注册系统 spring mvc spring jdbc

    这个项目是一个基于Spring MVC和Spring JDBC的简单用户管理应用,旨在帮助初学者理解如何在实际开发中实现用户登录、注册以及信息修改功能。Spring MVC是Spring框架的一个模块,主要用于构建Web应用程序,而Spring ...

    spring没有提示的时候

    在Spring框架的使用过程中,有时候我们可能会遇到"spring没有提示"的情况,这通常指的是Spring的自动提示、自动配置或者智能感知功能没有正常工作。这里我们将深入探讨Spring框架的一些核心概念和可能遇到的问题,...

    spring 4.3.14(全)最新的spring4正式版

    Spring 框架是 Java 开发中的一个核心组件,它为构建企业级应用程序提供了全面的编程和配置模型。Spring 4.3.14 是该框架...如果你的项目还在使用Java 7或者尚未准备迁移到Spring 5,那么这个版本会是一个可靠的选择。

    spring+动态代理

    在本篇中,我们将深入探讨Spring如何使用动态代理以及其在实际开发中的应用。 动态代理的核心概念是JDK的`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口。Proxy类用于创建一个代理对象,...

    spring对应jdk1.8的jar包

    然而,随着Java版本的升级,有时候不同版本的Spring和JDK之间可能会出现兼容性问题。在本例中,我们讨论的是Spring 3.2.0版本与JDK 1.8之间的冲突。 Spring 3.2.0发布于2012年,那时JDK 1.8尚未推出(JDK 1.8在2014...

    springcloud 完整练习项目

    在使用 Ribbon 的时候,服务消费者会在 Eureka 中获取服务提供者的信息,然后利用 Ribbon 进行轮询、随机等策略的负载均衡,从而选择一个合适的服务实例进行请求。 3. **Zuul**:Zuul 是 Spring Cloud 的边缘服务和...

    Spring自定义切面事务问题

    - 在Spring中,事务管理器本身也可以被看作是一种切面,它负责在合适的时候开启和提交事务。因此,当有多个切面需要被应用到同一个方法上时,切面的执行顺序就显得尤为重要。 - **通过`order`属性调整切面的...

    从ThreadLocal的使用到Spring的事务管理

    3. 在合适的时候,通过get方法获取当前线程的变量副本。 4. 不再使用时,调用remove方法清除线程局部变量,防止内存泄漏。 接下来,我们转向Spring框架的事务管理。Spring提供了声明式事务管理,开发者无需显式地...

    java单元测试 spring mock的使用

    在Spring中,Mock的使用可以模拟Web环境进行单元测试,不需要每一次都需要部署到容器里边。Mock会模拟Web环境,创建ApplicationContext和servletContext,加载配置文件,注册DAO和Manager类等。这样,在单元测试程序...

    Spring在容器在启动的时候发生了什么

    在Spring框架中,当一个基于Servlet的Web应用启动时,Spring容器的初始化过程是至关重要的。这个过程涉及到多个组件和步骤,让我们详细探讨一下。 首先,我们在`web.xml`配置文件中看到了`&lt;context-param&gt;`和`...

    spring data jpa 教程

    本教程将详细介绍 Spring Data JPA 的核心概念与使用方法,帮助开发者从基础入门到实现复杂查询的完整过程。 第一章:Spring Data JPA 入门 Spring Data JPA 简化了 JPA(Java Persistence API)的开发,通过约定...

    Spring AOP完整例子

    在本教程中,我们将深入探讨Spring AOP的不同使用方法,包括定义切点、通知类型、组装切面以及使用JUnit4进行测试。 首先,我们需要理解Spring AOP的基础概念。AOP的核心是切点(Pointcut),它定义了关注点在何处...

    spring源码报错缺失的两个包

    然而,有时候我们可能会遇到"spring源码报错缺失的两个包"这样的问题,这意味着我们的开发环境缺少了某些必要的依赖,导致Spring框架无法正常工作。在这个情况下,解决办法就是将这两个包添加到构建路径(build path...

    使用spring调度

    `ScheduledExecutorService`会根据触发器计算下次执行时间,并在适当的时候调用任务的`Runnable`接口。 7. **注意事项** - 调度任务应尽可能地无状态,避免并发执行时产生数据冲突。 - 调整线程池参数以平衡资源...

    spring aop ioc实例

    在实际操作中,你可以使用Spring Boot来快速启动一个Spring应用,它已经集成了Spring AOP和IOC的功能。 总结来说,Spring的IOC和AOP提供了强大的功能,帮助我们构建松散耦合、易于测试和维护的应用。通过理解并熟练...

    Spring使用XML配置声明式事务

    这使得Spring AOP(面向切面编程)能够拦截指定方法的执行,并在适当的时候启动、提交或回滚事务。 在实际应用中,我们可以在业务服务类的方法上添加@Transactional注解,以便Spring自动管理事务。例如: ```java ...

    Spring Boot 进阶笔记.pdf

    这也就是引入的 WEB 模块 starter 的时候不用指定版本号 &lt;version&gt; 标签的原因,因为在 spring-boot-starter-parent 中已经指定了,类似于一种继承的关系,父亲已经为你提供了,你只需要选择用不用就行。 Spring ...

    SpringBoot + Spring Security 基本使用及个性化登录配置详解

    在本文中,我们将介绍如何使用 SpringBoot 和 Spring Security 实现基本的认证和授权功能,并且实现个性化的登录配置。 一、Spring Security 简介 Spring Security 是一个基于 Spring 框架的安全框架,它提供了...

Global site tag (gtag.js) - Google Analytics