SpringMVC 事务配置完全详解

1.本设计采用springMVC+Hibernate ,事务控制在Service层,直接上代码

2.web.xml

<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    version="2.5"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <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>

    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter
        </filter-class>
    </filter>
    <filter-mapping>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <servlet-name>spring</servlet-name>
    </filter-mapping>
    <filter>
        <filter-name>openSessionInViewFilter</filter-name>
        <filter-class>
            org.springframework.orm.hibernate4.support.OpenSessionInViewFilter
        </filter-class>
    </filter>
    <filter-mapping>
        <filter-name>openSessionInViewFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <servlet>
        <servlet-name>springMVC3</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>springMVC3</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <session-config>
        <session-timeout>20</session-timeout>
    </session-config>

    <display-name>MeatBall</display-name>
    <welcome-file-list>
        <welcome-file>/admin/homepage</welcome-file>
    </welcome-file-list>
</web-app>

2. applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:task="http://www.springframework.org/schema/task"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
        http://www.springframework.org/schema/task
        http://www.springframework.org/schema/task/spring-task-3.0.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <context:annotation-config />

    <!-- 扫描Controller,Service,Reponsitory -->
    <context:component-scan base-package="com.zxd" >
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />

      <context:include-filter type="annotation" expression="org.springframework.stereotype.Service" />

      <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository" />

    </context:component-scan>

    <bean id="propertyConfigurer"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:resources.properties</value>
            </list>
        </property>
    </bean>

    <!-- 数据源 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
        destroy-method="close">
        <property name="driverClass" value="${connection.driver_class}" />
        <property name="jdbcUrl" value="${connection.url}" />
        <property name="user" value="${connection.username}" />
        <property name="password" value="${connection.password}" />
        <property name="maxPoolSize" value="80" />
        <property name="minPoolSize" value="1" />
        <property name="initialPoolSize" value="1" />
        <property name="maxIdleTime" value="20" />
    </bean>

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan">
            <list>
                <value>com.zxd.project.goods.model</value>
                <value>com.zxd.project.user.model</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.jdbc.batch_size">20</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
    </bean>

    <bean id="txManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="save*" propagation="REQUIRED" />
            <tx:method name="add*" propagation="REQUIRED" />
            <tx:method name="create*" propagation="REQUIRED" />
            <tx:method name="insert*" propagation="REQUIRED" />
            <tx:method name="update*" propagation="REQUIRED" isolation="READ_COMMITTED"/>
            <tx:method name="upload*" propagation="REQUIRED" />
            <tx:method name="merge*" propagation="REQUIRED" />
            <tx:method name="del*" propagation="REQUIRED" />
            <tx:method name="remove*" propagation="REQUIRED" />
            <tx:method name="clear*" propagation="REQUIRED" />
            <tx:method name="put*" propagation="REQUIRED" />
            <tx:method name="use*" propagation="REQUIRED" />
            <tx:method name="get*" propagation="REQUIRED" read-only="true" />
            <tx:method name="load*" propagation="REQUIRED" read-only="true" />
            <tx:method name="count*" propagation="REQUIRED" read-only="true" />
            <tx:method name="find*" propagation="REQUIRED" read-only="true" />
            <tx:method name="after*" propagation="REQUIRED" read-only="true" />
            <tx:method name="list*" propagation="REQUIRED" />
            <tx:method name="pag*" propagation="REQUIRED" />
            <tx:method name="query*" propagation="REQUIRED" read-only="true" />
        </tx:attributes>
    </tx:advice>

    <!-- 只对业务逻辑(service)层实施事务 -->
    <aop:config>
        <aop:pointcut id="txPointcut"
            expression="execution(* com.zxd..service.*.*(..))" />
        <aop:advisor  advice-ref="txAdvice" pointcut-ref="txPointcut" />
    </aop:config>
</beans>

3.application-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:sec="http://www.springframework.org/schema/security"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:task="http://www.springframework.org/schema/task"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/security
        http://www.springframework.org/schema/security/spring-security-3.2.xsd
        http://www.springframework.org/schema/task
        http://www.springframework.org/schema/task/spring-task-3.1.xsd ">

    <!-- 注解驱动 -->
    <mvc:annotation-driven>
        <mvc:message-converters>
            <!-- 中文编码 -->
            <bean class="com.zxd.common.util.UTF8StringHttpMessageConverter" />
        </mvc:message-converters>
    </mvc:annotation-driven> 

    <!-- 定时任务驱动 -->
    <task:annotation-driven/>  

    <context:component-scan base-package="com.zxd" >
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>
    </context:component-scan>

    <!-- 视图解析 -->
    <bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
        <!-- 返回的视图模型数据需要经过jstl来处理 -->
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/WEB-INF/jsp" />
        <property name="suffix" value=".jsp" />
    </bean>

    <!-- 对静态资源文件的访问 不支持访问WEB-INF目录 -->
    <mvc:default-servlet-handler />

    <!-- 对静态资源文件的访问 支持访问WEB-INF目录 -->
    <mvc:resources location="/static/" mapping="/static/**" />

    <bean id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!--one of the properties available;the maximum file size in bytes -->
        <property name="maxUploadSize" value="500000000" />
    </bean>

    <bean id="stringConverter" class="org.springframework.http.converter.StringHttpMessageConverter">
        <property name="supportedMediaTypes">
            <list>
                <value>text/plain;charset=UTF-8</value>
            </list>
        </property>
    </bean>

    <!-- 输出对象转JSON支持 -->
    <bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
    <bean
        class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="messageConverters">
            <list>
                <ref bean="stringConverter"/>
                <ref bean="jsonConverter" />
            </list>
        </property>
    </bean>

    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean id="ErrorInterceptor" class="com.zxd.common.interceptors.GlobleErrorInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

</beans>

4.以下为详解。

首先通过web.xml解析applicationContext(此为父容器)

    <!-- 扫描Controller,Service,Reponsitory -->
    <context:component-scan base-package="com.zxd" >
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />

      <context:include-filter type="annotation" expression="org.springframework.stereotype.Service" />

      <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository" />


    </context:component-scan>

在这段代码中,首先会吧com.zxd下的Controller,Service,Repository,注入到父容器中(可以不写Service,Repository,Controller,直接写成

<context:component-scan base-package="com.zxd" />也是可以的,Component-scan中就包含Service,Repository,Controller这一些注解,父容器是有事务控制的。

然后再来看
 <context:component-scan base-package="com.zxd" >
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>
    </context:component-scan>这段代码,在加载applicationContext-servlet.xml中一定要除去Service层,防止再次注入到父容器中,这个applicationContext-servlet是不具备事务控制的。

下面,摘一段控制台打印信息。


可以看到创建了食物,而且我在update*的isolation处改变了隔离级别。事务配置成功。那么下面再来看一下失败的。

在这里,我们可以看到,rollingBack,事务回滚成功。

如果您还想更深入了解,例如源码等,请捐赠我任意一笔金额。谢谢

时间: 2024-12-26 20:42:03

SpringMVC 事务配置完全详解的相关文章

idea spring+springmvc+mybatis环境配置整合详解

idea spring+springmvc+mybatis环境配置整合详解 1.配置整合前所需准备的环境: 1.1:jdk1.8 1.2:idea2017.1.5 1.3:Maven 3.5.2 2.查看idea中是否安装Maven插件: 2.1:File --> Settings --> Plugins 2.2:如下图所示的步骤进行操作(注:安装完插件,idea会重新启动) 3.idea创建Maven项目的步骤 4.搭建目录结构 下图就是我搭建Maven项目之后,添加对应的目录和文件 5.p

Spring事务管理(详解+实例)

写这篇博客之前我首先读了<Spring in action>,之后在网上看了一些关于Spring事务管理的文章,感觉都没有讲全,这里就将书上的和网上关于事务的知识总结一下,参考的文章如下: Spring事务机制详解 Spring事务配置的五种方式 Spring中的事务管理实例详解 1 初步理解 理解事务之前,先讲一个你日常生活中最常干的事:取钱. 比如你去ATM机取1000块钱,大体有两个步骤:首先输入密码金额,银行卡扣掉1000元钱:然后ATM出1000元钱.这两个步骤必须是要么都执行要么都

一篇非常经典的springMVC注解实现方式详解

今天公司让搭建个springMVC的注解框架,研究了好半天,网络搜罗了半天,好不容易找到篇,拿来分享下: 原文出处:http://www.itxxz.com/a/kuangjia/2014/0531/4.html 大家好,我是IT学习者的螃蟹,前两天写了一个spring MVC的注解实例,目前看来下载使用的人数已有不少,使用过程中也有不少人对其中的配置存有一些不解和疑问,在这里螃蟹就那个实例中的spring配置详细说明一下,算作是对spring注解模式的一次全方位解析.         在实例中

zookeeper的配置参数详解(zoo.cfg)

配置参数详解(主要是%ZOOKEEPER_HOME%/conf/zoo.cfg文件) 参数名 说明 clientPort 客户端连接server的端口,即对外服务端口,一般设置为2181吧. dataDir 存储快照文件snapshot的目录.默认情况下,事务日志也会存储在这里.建议同时配置参数dataLogDir, 事务日志的写性能直接影响zk性能. tickTime ZK中的一个时间单元.ZK中所有时间都是以这个时间单元为基础,进行整数倍配置的.例如,session的最小超时时间是2*tic

Mysql 配置参数详解以及优化配置

mysql有以下几种日志: 错误日志:   log-err 查询日志:   log 慢查询日志:  log-slow-queries 更新日志:   log-update 二进制日志: log-bin 要把日志生成在 /var/log 目录下(是系统日志存放的地方,只有 root 账号有写权限),需要 MySQL进程对这个目录有读写权限,一般是不这么做的,也考虑到安全问题,包括 MySQL 本身的数据安全,因为对 MySQL 的所有操作,都会记录到常规查询日志.MySQL的日志就不要用 /var

(转)Spring事务管理(详解+实例)

文章转自:http://blog.csdn.net/trigl/article/details/50968079 写这篇博客之前我首先读了<Spring in action>,之后在网上看了一些关于Spring事务管理的文章,感觉都没有讲全,这里就将书上的和网上关于事务的知识总结一下,参考的文章如下: Spring事务机制详解 Spring事务配置的五种方式 Spring中的事务管理实例详解 一.初步理解 理解事务之前,先讲一个你日常生活中最常干的事:取钱.  比如你去ATM机取1000块钱,

使用HeartBeat实现高可用HA的配置过程详解

使用HeartBeat实现高可用HA的配置过程详解 一.写在前面 HA即(high available)高可用,又被叫做双机热备,用于关键性业务.简单理解就是,有2台机器 A 和 B,正常是 A 提供服务,B 待命闲置,当 A 宕机或服务宕掉,会切换至B机器继续提供服务.常见的实现高可用的开源软件有 heartbeat 和 keepalived. 这样,一台 web 服务器一天24小时提供web服务,难免会存在 web 服务挂掉或服务器宕机宕机的情况,那么用户就访问不了服务了,这当然不是我们期望

Nginx实现集群的负载均衡配置过程详解

Nginx实现集群的负载均衡配置过程详解 Nginx 的负载均衡功能,其实实际上和 nginx 的代理是同一个功能,只是把代理一台机器改为多台机器而已. Nginx 的负载均衡和 lvs 相比,nginx属于更高级的应用层,不牵扯到 ip 和内核的修改,它只是单纯地把用户的请求转发到后面的机器上.这就意味着,后端的 RS 不需要配置公网. 一.实验环境 Nginx 调度器 (public 172.16.254.200 privite 192.168.0.48)RS1只有内网IP (192.168

SQL Server 事务隔离级别详解

原文:SQL Server 事务隔离级别详解 标签: SQL SEERVER/MSSQL SERVER/SQL/事务隔离级别选项/设计数据库事务级别 SQL 事务隔离级别 概述 隔离级别用于决定如果控制并发用户如何读写数据的操作,同时对性能也有一定的影响作用. 步骤 事务隔离级别通过影响读操作来间接地影响写操作:可以在回话级别上设置事务隔离级别也可以在查询(表级别)级别上设置事务隔离级别.事务隔离级别总共有6个隔离级别:READ UNCOMMITTED(未提交读,读脏),相当于(NOLOCK)R