最近在来到一个新公司,使用新的spring3,hibernate4框架,在使用注解事务总是不起作用。

首先看配置文件,然后再讲解。

首先是springmvc-servlet.xml,这个配置文件是servlet的加载文件,

引用这个文件的位置是在web.xml里

    <!-- 定义 springmvcServlet -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<!-- 默认/WEB-INF/[servlet名字]-servlet.xml加载上下文,
如果配置了contextConfigLocation参数,
将使用classpath:/springmvc-servlet.xml加载上下文
-->
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/springmvc-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 拦截匹配的请求,这里所有请求采用名字为mvc-dispatcher的DispatcherServlet处理 -->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
    <!-- 启动自动扫描该包下所有的Bean(例如@Controller)  这块很重要,会影响到事务-->
<context:component-scan base-package="com.bpz.demo" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:include-filter>
</context:component-scan> <!-- 定义视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>

然后是applicationcontext.xml

<!-- 启动自动扫描该包下所有的Bean  注意这块,也非常重要 -->
<context:component-scan base-package="com.bpz.demo" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Service"></context:include-filter>
<context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"></context:include-filter>
</context:component-scan>
<!-- Hibernate4 -->
<!-- 加载资源文件 其中包含变量信息,必须在Spring配置文件的最前面加载,即第一个加载-->
<context:property-placeholder location="classpath:mysql.properties" /> <bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan">
<list>
<!-- 可以加多个包 -->
<value>com.bpz.demo.entity</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
</props>
</property>
</bean> <!-- 数据库映射 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.user}" />
<property name="password" value="${jdbc.pass}" />
</bean>
<!-- 基于注释的事务,当注释中发现@Transactional时,使用id为“transactionManager”的事务管理器 -->
<!-- 如果没有设置transaction-manager的值,则spring以缺省默认的事务管理器来处理事务,默认事务管理器为第一个加载的事务管理器 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- 配置Hibernate事务管理器 -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>

引用位置是在web.xml里的

    <context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/applicationcontext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

以上是一个正确的配置方式,事务起作用完全没有问题。现在说说为什么很多时候配置的事务未起作用呢。

1.如果事务未起作用还未报错或异常,那应该是使用了sessionFactory.openSession(),在hibernate4里,如果使用spring来管理事务,需要使用

Session session = sessionFactory.getCurrentSession();来获取session。

2.如果使用了Session session = sessionFactory.getCurrentSession();来获取session有可能会报一个异常:

No Session found for current thread

为什么会出现这种情况呢,这和上面的配置就有关系了。一般情况下很多人为了省事,在servlet配置文件里直接

<context:component-scan base-package="com.bpz.demo">
</context:component-scan>

这样配置,对全部代码扫描,但是在servlet里并没有配置事务,所以事务完全不起作用.

不起作用的原因,在另一篇转载的文章里可以看到。

web.xml 中的listener、 filter、servlet 加载顺序及其详解

servlet是最后加载的,在最后使用

context:component-scan

扫描的时候,也会发现在有@Service,@Reposity等注解并进行实例化,由于在servlet配置文件里未配置事务,所以造成了事务不起作用,

看下面的源代码:

    public Session currentSession() throws HibernateException {
Object value = TransactionSynchronizationManager.getResource(this.sessionFactory);
if(value instanceof Session) {
return (Session)value;
} else if(value instanceof SessionHolder) {
SessionHolder session2 = (SessionHolder)value;
Session session1 = session2.getSession();
if(TransactionSynchronizationManager.isSynchronizationActive() && !session2.isSynchronizedWithTransaction()) {
TransactionSynchronizationManager.registerSynchronization(new SpringSessionSynchronization(session2, this.sessionFactory));
session2.setSynchronizedWithTransaction(true);
FlushMode flushMode = session1.getFlushMode();
if(flushMode.equals(FlushMode.MANUAL) && !TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
session1.setFlushMode(FlushMode.AUTO);
session2.setPreviousFlushMode(flushMode);
}
} return session1;
} else if(this.jtaSessionContext != null) {
Session session = this.jtaSessionContext.currentSession();
if(TransactionSynchronizationManager.isSynchronizationActive()) {
TransactionSynchronizationManager.registerSynchronization(new SpringFlushSynchronization(session));
} return session;
} else {
throw new HibernateException("No Session found for current thread");
}
}

1:@Transactional声明的方法执行时,Spring的TransactionManager会自动Open Session,自动开启事务,并且将此Sesion绑定到SpringSessionContext(实际上是TransactionSynchronizationManager的ThreadLocal的Map)中..而@Transactional的声明只有

tx:annotation-driven配置才会处理这个声明

2:SessionFactory.getCurrentSession()方法执行时,调用SpringSessionContext.currentSession()从TransactionSynchronizationManager的上下文中查找 当前的Session

3:找到后返回当前的Session,找不到,则返回HibernateException("No Session found for current thread")

对上面源代码的理解。

so:处理事务不起作用的办法就是servlet里做好自己的事,扫描@controller就可以了,这不但能加快启动速度,而且最主要的就是不会  画蛇添足。

												

画蛇添足-记spring3 hibernate4整合时遇到问题的处理办法的更多相关文章

  1. Struts2,Spring3,Hibernate4整合--SSH框架

    Struts2,Spring3,Hibernate4整合--SSH框架(学习中) 一.包的导入 1.Spring包 2.Hibernate 包 3.struts 包 (还欠 struts2-sprin ...

  2. spring3 hibernate4整合后无法查询数据库

    spring3和hibernate4整合后无法查询数据库,一方面是因为已经spring3中没有对hibernate4 HibernateTemplate的支持,另外一个就是需要在hibernate的配 ...

  3. hibernate4整合spring3事务问题

    本文是作者在对hibernate4+spring3+struts2整合中遇到的一个问题.对s2sh进行了基本的整合搭建以后,就是对事务的控制管理,将hibernate的事务交由spring管理.根据网 ...

  4. 使用Maven搭建Struts2+Spring3+Hibernate4的整合开发环境

    做了三年多的JavaEE开发了,在平时的JavaEE开发中,为了能够用最快的速度开发项目,一般都会选择使用Struts2,SpringMVC,Spring,Hibernate,MyBatis这些开源框 ...

  5. springmvc+spring3+hibernate4框架简单整合,简单实现增删改查功能

    转自:https://blog.csdn.net/thinkingcao/article/details/52472252 C 所用到的jar包     数据库表 数据库表就不用教大家了,一张表,很简 ...

  6. hibernate4整合spring3.1的过程中的异常问题

    (1)hibernate4整合spring3.1的过程中,发现了java.lang.NoClassDefFoundError: Lorg/hibernate/cache/CacheProvider异常 ...

  7. spring3+structs2整合hibernate4时报org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void sy.dao.impl.UserDaoImpl.setSessionFactory(org.hibernate.SessionFactory);

    今天在spring3+structs2整合hibernate4时报如下错误,一直找不到原因: org.springframework.beans.factory.BeanCreationExcepti ...

  8. Maven搭建Struts2+Spring3+Hibernate4框架

    做了三年多的JavaEE开发了,在平时的JavaEE开发中,为了能够用最快的速度开发项目,一般都会选择使用Struts2,SpringMVC,Spring,Hibernate,MyBatis这些开源框 ...

  9. mybatis和spring3.1整合

    因spring3发布时mybatis还没有出正式版本,所以spring没有整合最新的mybatis.不过社区倒是开发了一个中间件. 需要的jar包 mybatis-3.0.6.jar mybatis- ...

随机推荐

  1. PHP日期时间处理

    <?php //时区设置,可在php.ini文件中进行全局设置,默认使用的UTC时间 #date_default_timezone_set("Asia/Chongqing") ...

  2. Jeasyframe 开源框架 稳定版 V1.5 发布

    这是Jeasyframe开源框架的第一个稳定版本,感谢一起帮忙测试并给予反馈的网友们. 框架官网:http://www.jeasyframe.org/ 产品介绍: Jeasyframe开源框架是基于S ...

  3. [转]新兵训练营系列课程——平台RPC框架介绍

    原文:http://weibo.com/p/1001643875439147097368 课程大纲 1.RPC简介 1.1 什么是RPC 1.2 RPC与其他远程调用方式比较 2.Motan RPC框 ...

  4. IIS问题解决:URL中制表符引起的Bad Request - Invalid URL

    昨天处理好了Google网站管理员中的500错误,今天处理了一些400处理,比如下面的以制表符(tab)结尾的URL: http://www.cnblogs.com/me-sa/archive/200 ...

  5. DDD领域驱动设计之运用层代码

    1.DDD领域驱动设计实践篇之如何提取模型 2.DDD领域驱动设计之聚合.实体.值对象 3.DDD领域驱动设计之领域基础设施层 4.DDD领域驱动设计之领域服务 5.整体DEMO代码 什么是运用层,说 ...

  6. [游戏模版11] Win32 动画 时间消息

    >_<:This time we will study a new way to operate your picture.That is running your picture by ...

  7. [python爬虫] Selenium定向爬取海量精美图片及搜索引擎杂谈

    我自认为这是自己写过博客中一篇比较优秀的文章,同时也是在深夜凌晨2点满怀着激情和愉悦之心完成的.首先通过这篇文章,你能学到以下几点:        1.可以了解Python简单爬取图片的一些思路和方法 ...

  8. 从range和xrange的性能对比到yield关键字(中)

    上节提出了range和xrange的效率问题,这节我们来探究其中的原因   yield的使用   我们看下面的程序: #coding: utf-8 def test(): print 4 print ...

  9. Arduino单片机使用和开发问题记录

    1.将程序上传到板子时Arduino IDE提示“avrdude: stk500_getsync(): not in sync: resp=0x00” 网上查遇到这个问题的人比较多,有说驱动问题的,有 ...

  10. android: 服务的基本用法

    9.3   服务的基本用法 了解了 Android 多线程编程的技术之后,下面就让我们进入到本章的正题,开始对服务 的相关内容进行学习.作为 Android 四大组件之一,服务也少不了有很多非常重要的 ...