spring事务

springmvc事务的配置方式

springmvc配置事务方式有五种,好多都不怎么常用,说白了就是我也不会,最常用的基于注解的我还是有一些了解。我们来一起学习一下springmvc的事务配置方式。
首先来看声明式事务

  • 1 使用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>

这种主要是要求开发者在方法起名的时候需要保持前缀一直。

  • 2 使用代理的方式
<!-- 第二种配置事务的方式 ,代理-->
<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>

感觉和第一种很像,只是实现的方式不一样而已

  • 3 使用拦截器
<!-- 第三种配置事务的方式,拦截器 (不常用)-->
<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>

这个就更少用了

  • 4 使用全注解
    这个就使用的很多了,我也就会使用这一种。因为这个使用很简单。直接看配置和代码
 <!--数据库事务注解支持-->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

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

再看一下代码:

    //首先设置为requried
    @Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
    public void insert() {
        User user = new User();
        user.setName("yuxi");
       int pk =  userDao.insert(user);
        //新增账单
        orderService.insert(pk);
        System.out.println("......");
    }
  • 5 编程式
    意思就是自己在代码里实现事务,这个还是一个比较好的方式,可以精确的控制边界。
    TransactionTemplate tt = new TransactionTemplate(); // 新建一个TransactionTemplate
    Object result = tt.execute(
        new TransactionCallback(){  
            public Object doTransaction(TransactionStatus status){  
                updateOperation();  
                return resultOfUpdateOperation();  
            }  
    }); // 执行execute方法进行事务管理

springmvc事务的传播行为

事务的传播行为有七种,接下来我们就一种一种探讨一下。

    1. propagation_required 默认的
      具体来说就,如果当前没有事务就会新建一个事务,如果有事务就会加入当前事务。
 //首先设置为requried
    @Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
    public void insert() {
        User user = new User();
        user.setName("yuxi");
       int pk =  userDao.insert(user);
        //新增账单
       //因为有事务所有,orderService.insert(pk)会加入当前事务
        orderService.insert(pk);
    }

总结起来就是这两个方法要么一起执行,要么一起回滚,不会一个执行成功,另外一个执行回滚。

流程图
  • 2 propagation_requried_new
    具体来说就是,methodA设置为requried,methodB设置为requried_new,当执行methodB的时候,会先挂起methodA,等待methodB执行完了,methodA才继续执行。
    requried和requried_new 区别
    主要在于回滚程度了,methodB是新启的一个事务。
    如果methodB执行失败,methodB肯定回滚,如果methodA捕获这个异常,methodA可以正常提交,如果methodA没有捕获methodA也回滚。
    如果methodB执行成功,methodA执行失败,那么methodB不会回滚,methodA会执行回滚。
    //首先设置为requried
    @Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
    public void insert() {
        User user = new User();
        user.setName("yuxi");
       int pk =  userDao.insert(user);
        //requried_new ,如果执行失败
        try {
            orderService.insert(pk);
        }catch (Exception e){
            //不做处理,让当前事务执行完
        }
        System.out.println("......");
    }

  //requried_new
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
    public  void insert(int userId) {
        Order order = new Order();
        order.setDescs("desc yx");
        order.setOrderId("0101");
        order.setUserId(userId);
        orderDao.insert(order);
        int i = 1/0;
    }

执行结果:
user表有数据,order表没有数据。
我们在换成另外一种情况, orderService.insert(pk);执行成功

 //首先设置为requried
    @Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
    public void insert() {
        User user = new User();
        user.setName("yuxi");
       int pk =  userDao.insert(user);
        //requried_new ,如果执行失败
//        try {
            orderService.insert(pk);
//        }catch (Exception e){
//            //不做处理,让当前事务执行完
//        }
        int i = 1/0;
        System.out.println("......");
    }


 //requried_new
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
    public  void insert(int userId) {
        Order order = new Order();
        order.setDescs("desc yx");
        order.setOrderId("0101");
        order.setUserId(userId);
        orderDao.insert(order);
//        int i = 1/0;
    }

执行结果:
order表有数据,user没有数据。

流程图
  • 3 propagation_nested
    具体来说,就是嵌套事务。

第一种情况:
nested事务抛了异常,外部事务捕获了异常。

 //首先设置为requried
    @Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
    public void insert() {
        User user = new User();
        user.setName("yuxi");
       int pk =  userDao.insert(user);
        //NESTED ,如果执行失败
        try {
            orderService.insert(pk);
        }catch (Exception e){
            System.out.println("可以继续执行这里面的逻辑.....");
        }
        System.out.println("当前事务继续执行......");
    }
 //NESTED
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NESTED)
    public  void insert(int userId) {
        Order order = new Order();
        order.setDescs("desc yx");
        order.setOrderId("0101");
        order.setUserId(userId);
        orderDao.insert(order);
        int i = 1/0;
    }

结果是:
外部事务正常执行,嵌套事务回滚。
第二种情况:嵌套事务正常执行完成,外部事务抛了异常。

   //首先设置为requried
    @Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
    public void insert() {
        User user = new User();
        user.setName("yuxi");
       int pk =  userDao.insert(user);
        //NESTED ,如果执行失败
        try {
            orderService.insert(pk);
        }catch (Exception e){
            System.out.println("可以继续执行这里面的逻辑.....");
        }
        int i = 1/0;
        System.out.println("当前事务继续执行......");
    }
 //NESTED
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NESTED)
    public  void insert(int userId) {
        Order order = new Order();
        order.setDescs("desc yx");
        order.setOrderId("0101");
        order.setUserId(userId);
        orderDao.insert(order);
//        int i = 1/0;
    }

结果是:
两个都被回滚了,我理解这个就是嵌套事务和requried_new 的最大区别了。

  • 4 propagation_supported
    具体来说,就是支持当前事务,如果没有就以非事务的方式运行。

  • 5 propagation_not_supported
    具体来说就是不支持以事务的方式运行,如果当前有事物就会挂起。

  • 6 propagation_never
    具体来说,就是不支持事务的方式运行,如果有事务就会抛出异常。

  • 7 propagation_mandatory
    具体来说,就是支持当前事务,如果当前没有事务,就抛出异常。
    后面的基本都不常用。

参考文章:
http://blog.csdn.net/it_wangxiangpan/article/details/24180085
http://blog.csdn.net/paincupid/article/details/48185597

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容

  • 很多人喜欢这篇文章,特此同步过来 由浅入深谈论spring事务 前言 这篇其实也要归纳到《常识》系列中,但这重点又...
    码农戏码阅读 4,699评论 2 59
  • Spring事务机制主要包括声明式事务和编程式事务,此处侧重讲解声明式事务,编程式事务在实际开发中得不到广泛使用,...
    EnigmaXXX阅读 667评论 0 0
  • 1. 关于事务 事务控制就是将一系列操作当成一个不可拆分的逻辑单元,保证这些操作要么都成功,要么都失败。在关系数据...
    七弦桐语阅读 2,880评论 0 14
  • 深入理解 Spring 事务原理参考:https://mp.weixin.qq.com/s/HHLGfRuD_Yn...
    it_zzy阅读 758评论 0 8
  • 1. 事务基础 1.1 什么是事务 所谓事务就是用户定义的一个数据库操作序列,这些操作要么全做,要么全不做,是一个...
    执笔弄风月阅读 502评论 0 0