配置spring事务管理的几种方式(声明式事务)

概要:

  Spring对编程式事务的支持与EJB有很大的区别。不像EJB和Java事务API(Java Transaction API, JTA)耦合在一起那样,Spring通过回调机制将实际的事务实现从事务性的代码中抽象出来。实际上,Spring对事务的支持甚至不需要JTA的实现。如果你的应用程序只使用一种持久化资源,Spring可以使用持久化本事所提供的事务性支持,这包括了JDBC,Hibernate以及Java持久化API(Java Persistence API,JPA)。但是如果应用程序的事务跨多个资源,那么Spring会使用第三方的JTA实现来支持分布式(XA)事务。

  编码式事务允许用户在代码中精确定义事务的边界,而声明式事务(基于AOP)有助于用户将操作与事务规则经行解耦。无论选择将事务编码到Bean中还是将选择其定义为切面,我们都需要使用Spring事务管理器与平台相关的事务经行交互。(也就是无论选择编码式还会声明式,都需要在XML中定义事务管理器)。

Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource、TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是代理机制这部分。

DataSource、TransactionManager这两部分只是会根据数据访问方式有所变化,比如使用Hibernate进行数据访问时,DataSource实际为SessionFactory,TransactionManager的实现为HibernateTransactionManager。

具体如下图:

根据4种代理机制的不同,总结了五种Spring事务的配置方式。

目录:

  1. Bean和代理
  2. 使用拦截器
  3. 使用Tx标签配置的拦截器
  4. 全注解配置

声明式事务

 

公共配置

<?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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
 <bean id="sessionFactory"
            class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="configLocation" value="classpath:hibernate.cfg.xml" />
        <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />
    </bean> 

<!-- 定义事务管理器(声明式的事务) -->
<bean id="hibernateTransactionManager"
      class="org.springframework.orm.hibernate3.HibernateTransactionManager">
      <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
  <!-- 配置DAO -->
    <bean id="userDaoTarget" class="com.bluesky.spring.dao.UserDaoImpl">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

第一种,使用tx标签方式

<!-- 第一种配置事务的方式 ,tx-->
<tx:advice id="txadvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="add*" propagation="REQUIRED" rollback-for="Exception" />
        <tx:method name="modify*" propagation="REQUIRED" rollback-for="Exception" />
        <tx:method name="del*" propagation="REQUIRED" rollback-for="Exception"/>
        <tx:method name="*" propagation="REQUIRED" read-only="true"/>
    </tx:attributes>
</tx:advice>

<aop:config>
    <aop:pointcut id="daoMethod" expression="execution(* com.dao.*.*(..))"/>
    <aop:advisor pointcut-ref="daoMethod" advice-ref="txadvice"/>
</aop:config>

expression="execution(* com.dao.*.*(..))"
其中第一个*代表返回值,第二*代表dao下子包,第三个*代表方法名,“(..)”代表方法参数。

第二种,使用代理方式

<!-- 第二种配置事务的方式 ,代理-->
<bean id="transactionProxy"
    class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"    abstract="true">
    <property name="transactionManager" ref="transactionManager"></property>
    <property name="transactionAttributes">
        <props>
            <prop key="add*">PROPAGATION_REQUIRED, -Exception</prop>
            <prop key="modify*">PROPAGATION_REQUIRED, -Exception</prop>
            <prop key="del*">PROPAGATION_REQUIRED, -Exception</prop>
            <prop key="*">PROPAGATION_REQUIRED, readOnly</prop>
        </props>
    </property>
</bean>
<bean id="userDao" parent="transactionProxy">
    <property name="target">
        <!-- 用bean代替ref的方式-->
        <bean class="com.dao.UserDaoImpl">
            <property name="sessionFactory" ref="sessionFactory"></property>
        </bean>
    </property>
</bean>

将transactionProxy的abstract属性设置为"true",然后将具体的Dao的parent属性设置为"transactionProxy",可以精简代码。

第三种,使用拦截器

<!-- 第三种配置事务的方式,拦截器 (不常用)-->
<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
    <property name="transactionManager" ref="transactionManager"></property>
    <property name="transactionAttributes">
        <props>
            <prop key="add*">PROPAGATION_REQUIRED, -Exception</prop>
            <prop key="modify*">PROPAGATION_REQUIRED, -Exception</prop>
            <prop key="del*">PROPAGATION_REQUIRED, -Exception</prop>
            <prop key="*">PROPAGATION_REQUIRED, readOnly</prop>
        </props>
    </property>
</bean>
<bean id="proxyFactory" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
    <property name="interceptorNames">
        <list>
            <value>transactionInterceptor</value>
        </list>
    </property>
    <property name="beanNames">
        <list>
            <value>*Dao</value>
        </list>
    </property>
</bean>

Bean和代理

第一种方式:每个Bean都有一个代理

<?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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">

    <bean id="sessionFactory"
            class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="configLocation" value="classpath:hibernate.cfg.xml" />
        <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />
    </bean>  

    <!-- 定义事务管理器(声明式的事务) -->
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <!-- 配置DAO -->
    <bean id="userDaoTarget" class="com.bluesky.spring.dao.UserDaoImpl">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <bean id="userDao"
        class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
           <!-- 配置事务管理器 -->
           <property name="transactionManager" ref="transactionManager" />
        <property name="target" ref="userDaoTarget" />
         <property name="proxyInterfaces" value="com.bluesky.spring.dao.GeneratorDao" />
        <!-- 配置事务属性 -->
        <property name="transactionAttributes">
            <props>
                <prop key="*">PROPAGATION_REQUIRED</prop>
            </props>
        </property>
    </bean>
</beans>

总结:

  1. 定义数据源  
  2. 定义事务管理器(将数据源加入)
  3. 定义Dao Bean(将数据源加入)
  4. 定义TransactionProxyFactoryBean代理Bean,将事务管理器,Dao Bean加入。

第二种方式:所有Bean共享一个代理基类

<?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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
 <bean id="sessionFactory"
            class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="configLocation" value="classpath:hibernate.cfg.xml" />
        <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />
    </bean> 

<!-- 定义事务管理器(声明式的事务) -->
<bean id="hibernateTransactionManager"
      class="org.springframework.orm.hibernate3.HibernateTransactionManager">
      <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

    <bean id="HibernateProxyTemplate"
          abstract="true"
          class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
                <!-- 配置事务管理器 -->
         <property name="transactionManager">
            <ref bean="hibernateTransactionManager"/>
         </property>
              <!-- 配置事务属性 -->
         <property name="transactionAttributes">
            <props>
                <prop key="create*">
                    PROPAGATION_REQUIRED,-java.lang.Exception
                </prop>
                <prop key="reg*">
                    PROPAGATION_REQUIRED,-java.lang.Exception
                </prop>
                <prop key="apply*">
                    PROPAGATION_REQUIRED,-java.lang.Exception
                </prop>
                <prop key="add*">
                    PROPAGATION_REQUIRED,-java.lang.Exception
                </prop>
                <prop key="remove*">
                    PROPAGATION_REQUIRED,-java.lang.Exception
                </prop>
                <prop key="update*">
                    PROPAGATION_REQUIRED,-java.lang.Exception
                </prop>
                <prop key="delete*">
                    PROPAGATION_REQUIRED,-java.lang.Exception
                </prop>
             <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
            </props>
        </property>
    </bean>    
 <bean id="userDao" class="edu.fjnu.hotelsys.dao.UserDaoHibernateImpl">
      <property name="sessionFactory" ref="sessionFactory"></property>
   </bean>

   <bean id="userServiceTarget" class="edu.fjnu.hotelsys.service.UserServiceImpl">
      <property name="userDao" ref="userDao"></property>
   </bean>

   <bean id="userService" parent="HibernateProxyTemplate">
       <property name="target">
          <ref bean="userServiceTarget"/>
       </property>
   </bean>
   

只要指明它的parent(父类)就可以了。父类一般把abstract="true",因为在容器加载的时候不需要初始化,等到用的时候再有它的子类调用的时候,再去初始化。

总结:

  1. 定义数据源  
  2. 定义事务管理器(将数据源加入),且将事务管理器声明为abstract="true"
  3. 定义Dao Bean(将数据源加入)
  4. 定义TransactionProxyFactoryBean代理Bean,将事务管理器,Dao Bean加入。

使用拦截器

<?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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">

    <bean id="sessionFactory"
            class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="configLocation" value="classpath:hibernate.cfg.xml" />
        <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />
    </bean>  

    <!-- 定义事务管理器(声明式的事务) -->
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean> 

    <bean id="transactionInterceptor"
        class="org.springframework.transaction.interceptor.TransactionInterceptor">
        <property name="transactionManager" ref="transactionManager" />
        <!-- 配置事务属性 -->
        <property name="transactionAttributes">
            <props>
                <prop key="*">PROPAGATION_REQUIRED</prop>
            </props>
        </property>
    </bean>

    <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
        <property name="beanNames">
            <list>
                <value>*Dao</value>
            </list>
        </property>
        <property name="interceptorNames">
            <list>
                <value>transactionInterceptor</value>
            </list>
        </property>
    </bean>  

    <!-- 配置DAO -->
    <bean id="userDao" class="com.bluesky.spring.dao.UserDaoImpl">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
</beans>

使用tx标签配置的拦截器

<?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:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

    <context:annotation-config />
    <context:component-scan base-package="com.bluesky" />

    <bean id="sessionFactory"
            class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="configLocation" value="classpath:hibernate.cfg.xml" />
        <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />
    </bean>  

    <!-- 定义事务管理器(声明式的事务) -->
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="*" propagation="REQUIRED" />
        </tx:attributes>
    </tx:advice>

    <aop:config>
        <aop:pointcut id="interceptorPointCuts"
            expression="execution(* com.bluesky.spring.dao.*.*(..))" />
        <aop:advisor advice-ref="txAdvice"
            pointcut-ref="interceptorPointCuts" />
    </aop:config>
</beans>

全注解

<?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:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

    <context:annotation-config />
    <context:component-scan base-package="com.bluesky" />

    <tx:annotation-driven transaction-manager="transactionManager"/>

    <bean id="sessionFactory"
            class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="configLocation" value="classpath:hibernate.cfg.xml" />
        <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />
    </bean>  

    <!-- 定义事务管理器(声明式的事务) -->
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

</beans>

此时在DAO上需加上@Transactional注解,如下:

package com.bluesky.spring.dao;

import java.util.List;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Component;

import com.bluesky.spring.domain.User;

@Transactional
@Component("userDao")
public class UserDaoImpl extends HibernateDaoSupport implements UserDao {

    public List<User> listUsers() {
        return this.getSession().createQuery("from User").list();
    }

}

文章出自:http://www.cnblogs.com/longshiyVip/p/5061547.html

事务管理(下) 配置spring事务管理的几种方式(声明式事务)的更多相关文章

  1. 配置spring事务管理的几种方式(声明式事务)

    Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource.TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是代理机制这部分. DataSo ...

  2. spring整合mybatis,ioc容器及声明式事务配置

    步骤: 1.创建jdbc.properties文件,用来管理存放连接数据库的相关信息 jdbc.properties:jdbc.user=root jdbc.password=123456 jdbc. ...

  3. Spring框架(三) JDBCTemplate,声明式事务,自动装载(注解)

    JDBCTemplate 按照标准正常项目的结构 结构图: model层 dao层 实现  dao:(DateBase Access Object) 数据访问对象,dao层只用来访问数据库和模型层 s ...

  4. Spring注解驱动开发(四)-----aop、声明式事务

    AOP 概念 指在程序运行期间动态的将某段代码切入到指定方法指定位置进行运行的编程方式:-----基于动态代理 一个aop示例 1.导入aop模块:Spring AOP:(spring-aspects ...

  5. 第一课:Centos下配置java环境变量的两种方式(jdk1.8)

    配置java环境(yum安装) 1.查出java1.8的全部版本 yum list java-1.8* 2.安装你需要的java1.8 版本(安装的名字根据查询出来的结果输入这里只是举例) yum i ...

  6. 全面分析 Spring 的编程式事务管理及声明式事务管理

    开始之前 关于本教程 本教程将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. 先决条件 本 ...

  7. 全面分析 Spring 的编程式事务管理及声明式事务管理--转

    开始之前 关于本教程 本教程将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. 先决条件 本 ...

  8. spring事务管理——编程式事务、声明式事务

    本教程将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. 先决条件 本教程假定您已经掌握了 ...

  9. Spring编程式事务管理及声明式事务管理

    本文将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. Spring 事务属性分析 事务管理 ...

随机推荐

  1. sql语句把字段中的某个字符去掉

    sql语句把字段中的某个字符去掉 )),'http://demo.m-school.net','') 例如: )),'http://192.168.2.180','') )),'http://zpzx ...

  2. iphone H5视频行内播放(禁止全屏播放)

    一般用户都知道,ios在网页点击视频播放时,视频会弹出全屏播放框. video标签的playsinline.webkit-playsinline标记根本就不会起作用. 还有传闻说对于没有声音的视频不会 ...

  3. iframe载入页面过程显示动画效果

    http://www.xfeixiang.com/Bug/Detail/A2FD7EFFA8CA72F1

  4. Wireshark工控协议

    Wireshark是一个强大开源流量与协议分析工具,除了传统网络协议解码外,还支持众多主流和标准工控协议的分析与解码. 序号 协议类型 源码下载 简介 1 Siemens S7 https://git ...

  5. myeclipse2014新建maven项目

    1,首先安装maven,并配置. 2,新建maven project. 3,选择maven-archetype-webapp. 4,填写afrifact ID即为项目名称. 5,finish后 bui ...

  6. oracle中scn(系统改变号)

    系统scn:                 select checkpoint_change# from v$database; 文件scn:                 select name ...

  7. Unable to execute dex: GC overhead limit exceeded

    Android打包时下面的错误: Unable to execute dex: GC overhead limit exceeded GC overhead limit exceeded 解决的方法: ...

  8. C#在高性能计算领域为什么性能却如此不尽人意

    C#的优雅,强大IDE的支持,.net下各语言的二进制兼容,自从第一眼看到C#就被其良好的设计吸引.一直希望将其应用于高性能计算领域,长时间努力却效果却不尽如人意. 对于小的测试代码用例而言,C#用2 ...

  9. Hello Spring Framework——面向切面编程(AOP)

    本文主要参考了Spring官方文档第10章以及第11章和第40章的部分内容.如果要我总结Spring AOP的作用,不妨借鉴文档里的一段话:One of the key components of S ...

  10. Gradle使用小结

    Gradle是CI过程工具,而不是系统.持续集成过程中的构建.自动化测试.打包.发布都可以使用Gradle来完成.而持续进程过程为我们降低各方面成本,提高产品信心,提高产品质量有着非常重要的作用(不要 ...