文档章节

spring事务管理总结

LIFeForYoung1
 LIFeForYoung1
发布于 2017/05/03 21:30
字数 1102
阅读 7
收藏 1

最近在写一个项目,用到了spring事务管理。自己也在这总结一下:

Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource、TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是代理机制这部分。 DataSource、 TransactionManager这两部分只是会根据数据访问方式有所变化,比如使用Hibernate进行数据访问时,DataSource实际为 SessionFactory,TransactionManager的实现为HibernateTransactionManager。 下面一起看看三种声明式事务的具体配置:

 

声明式事务

 

公共配置

<!-- 配置sessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="configLocation">
        <value>classpath:config/hibernate.cfg.xml</value>
    </property>
    <property name="packagesToScan">
        <list>
            <value>com.entity</value>
        </list>
    </property>
</bean>

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

<!-- 配置DAO --> 
<bean id="userDao" class="com.dao.UserDaoImpl">
    <property name="sessionFactory" ref="sessionFactory"></property>
</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>

 

Spring事务类型详解:

 

PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。

PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。

PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。

PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。

PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。

PROPAGATION_NESTED--如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。

 

编程式事务

 

编程式即采用注解的方式,需要注意的是,使用注解的方式需要在Spring的配置文件中加入一句话:<context:annotation-config />,其作用是开启注解的方式。具体配置如下:

<!--开启注解方式-->
<context:annotation-config />

<!-- 配置sessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="configLocation">
        <value>classpath:config/hibernate.cfg.xml</value>
    </property>
    <property name="packagesToScan">
        <list>
            <value>com.entity</value>
        </list>
    </property>
</bean>

<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"></property>
</bean>

<!-- 第四种配置事务的方式,注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/>

 

注解文件:

package com.dao;

import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.entity.User;

@Transactional
public class UserDaoImpl_BAK extends HibernateTemplate {

    @Transactional(propagation=Propagation.REQUIRED,rollbackForClassName="Exception")
    public void addUser(User user) throws Exception {
        this.save(user);
    }

    @Transactional(propagation=Propagation.REQUIRED,rollbackForClassName="Exception")
    public void modifyUser(User user) {
        this.update(user);
    }

    @Transactional(propagation=Propagation.REQUIRED,rollbackForClassName="Exception")
    public void delUser(String username) {
        this.delete(this.load(User.class, username));
    }

    @Transactional(readOnly=true)
    public void selectUser() {

    }

}


类头的@Transactional为默认事务配置,如方法没有自己的事务类型,则按默认事务,如有自己的配置,则按自己的配置。

 

以上四种配置方式最常用的还是第一、二种,第三种是比较老旧的方式,而注解的方式不太适合比较大的项目,用于简单的小项目还是很好的,其特点就是简单明了。每种方法都有每种方法的特点跟适用的环境,没有绝对的好与坏,只不过前两种在实际的工作当中用的更多一些。

© 著作权归作者所有

LIFeForYoung1
粉丝 0
博文 12
码字总数 4382
作品 0
绵阳
私信 提问
Spring的事务管理实现原理初探

这里主要是通过分析部分源码进行剖析Spring事务管理的实现原理。 再分析源码前,现从理论上大概分析哈: 纯JDBC操作数据库的基本步骤: 1. 获取连接 Connection conn = DriverManager.getCon...

rockypeng
2014/01/19
0
0
分析总结Spring管理Hibernate中Dao层访问数据库常用方式(附SSH的jar包)

上篇博客中已经讲解Spring配置数据源的常用的几种方式。接下来本篇博客继续讲解。配置完数据源,那Dao层是如何访问数据库呢? 基于最近的项目使用SSH2框架完成,分析总结Spring与Hibernate集...

晨曦之光
2012/08/22
588
0
Spring编程式和声明式事务

1.编程式事务 1.1 编程式和声明式事务的区别 Spring提供了对编程式事务和声明式事务的支持,编程式事务允许用户在代码中精确定义事务的边界,而声明式事务(基于AOP)有助于用户将操作与事务...

梨加橙
2018/06/19
0
0
Spring Test 整合 JUnit 4 使用总结

加入依赖包   使用Spring的测试框架需要加入以下依赖包: JUnit 4 (官方下载:https://github.com/KentBeck/junit/downloads) Spring Test (Spring框架中的test包) Spring 相关其他依赖...

backtract
2013/11/04
0
0
Spring MVC + Mybatis + Spring Aop声明式事务管理没有作用

在最近的一个项目中,采用springMVC、mybatis,发现一个很恼人的问题:事务管理不起作用!!网上查阅了大量的资料,尝试了各种解决办法,亦未能解决问题! applicationContext.xml配置: sp...

陶邦仁
2016/01/03
908
0

没有更多内容

加载失败,请刷新页面

加载更多

阿里云POLARDB如何助力轻松筹打造5亿用户信赖的大病筹款平台?

轻松筹首创了“大病救助”模式,帮助了众多病患在第一时间解決了医疗资金等问题,为了从源头解决了医疗资金问题。而在轻松筹这样全球5.5亿用户信赖的大病筹款平台的背后,是日益增长的各种数...

阿里云云栖社区
4分钟前
1
0
Confluence 6 在升级过程中查看合并日志

为了监控升级的过程,你应该查看 application log 日志中的输出。 通常日志经常将会显示多个日志实例,这个实例是定义在日志的 INFO 级别的,通常格式如下: WikiToXhtmlMigrationThread-n -...

honeymoose
4分钟前
0
0
git diff 文件对比

git diff filepath 工作区与暂存区比较 git diff HEAD filepath 工作区与HEAD ( 当前工作分支) 比较 git diff --staged 或 --cached filepath 暂存区与HEAD比较 git diff branchName filepa......

李佳顺
4分钟前
0
0
spring mvc 定制化配置

spring mvc 自定义配置 1.实现某些接口,然后让上面的类加载进去. class MyHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver { @Override public boolean......

最爱肉肉
7分钟前
0
0
OSG_采样像机的内容如果不显示到窗口上

cameraLight->setRenderTargetImplementation(Camera::FRAME_BUFFER_OBJECT);// 这句使内容不渲染到屏幕上cameraLight->setRenderOrder(Camera::PRE_RENDER); 1.setRenderTargetImplement......

洛克人杰洛
10分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部