前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ssm整合,事务,aop,事务传播为什么失效???

ssm整合,事务,aop,事务传播为什么失效???

作者头像
废江_小江
发布2022-09-05 14:02:14
2080
发布2022-09-05 14:02:14
举报
文章被收录于专栏:总栏目

背景

好久没写博客了,今天小写一篇博客,简单写一遍ssm整合,其实之前已经写过了,在layui快速开发这篇博客里,这次主要写出原理以及细节,和一些demo

这里主要说下spring配置mybatis,以及配置ssm的原理步骤。

整合ssm

网上很多人觉得很复杂,其实我觉得还是很好记忆的。

具体的配置代码,看下这篇博客,ssm整合

其实,配置ssm整合无非就是配置spring,springmvc,mybatis

从web.xml里面配置spring和springmvc,即一个spring的上下文和一个前端控制器。

mybatis的整合则是在spring的配置文件中整合,主要就是配置一个sql工厂,这个sql工厂需要一个datasource数据源,以及一些其他的mybatis的信息,例如配置文件,和mapper.xml文件的位置等待。

这些配置完,整合就结束了!

spring事务

事务简介

首先需要理解什么是事务,为什么需要事务

事务的定义就是,一组操作,组成这些操作的一个个单元。要么全部成功,要么全部失败。

为什么需要事务?比如,一个业务中,需要的不只是一组sql操作。例如转账中,需要给一个账号增加余额以及对应的账号减少余额,并且这两个sql操作是不可分割的,因此需要一个事务将其绑定起来。

spring事务

什么是spring中的事务?mysql是支持事务的,原始的jdbc中如何使用呢?

原始中,我们是start开启一个事务,然后进行sql操作,如果发生了意外,则roll回滚,如果没啥问题就commit提交事务。但是这样的写法直接耦合死了。例如,这个业务的事务我都不想要了,那么你就需要一段段去删除。例如给这个业务中的方法全部加上业务,你又要一段段去增加。因此,spring看出来了我们的难处。spring大手一拍,我来帮你管理吧。

spirng中的事务则是基于aop原理,帮你管理。你只需要进行配置就行了。这里重点说下注解配置,因为注解比较简单。使用

代码语言:javascript
复制
@Transactional

注解,加在哪写方法上,就可以代表这整个方法是一个事务。

代码语言:javascript
复制
@Transactional
public void transact(Account a,Account b,Double nums){
    Map<String, Object> map1 = MapParameter.getInstance()
            .add("account",a)
            .add("nums",nums)
            .getMap();
    mapper.updateBalance2(map1);
    int i = 10/0;
    Map<String, Object> map2 = MapParameter.getInstance()
            .add("account",b)
            .add("nums",nums)
            .getMap();
    mapper.updateBalance(map2);
}

事务注解一般都是加在业务层,加在业务的接口上表示整个业务层的方法开启了事务。

事务传播

代码语言:javascript
复制
/**
 * 测试事务的传播行为
 * 账号a向一个账号集合b中的所有账号转账
 * 对应的业务,例如公司发工资
 *
 * 发生条件,一个方法自身加了事务,然后调用另一个方法也加了事务,这时调用的方法是使用自己的事务,还是该方法的事务呢?
 * 例如这里我给moreTransact方法加上了@Transactional注解,这时默认的是REQUIRED
 *      默认值的意思,通俗的说就是把你这个外层的方法看作一个事务,要么转账全部成功,要么转账全部失败,如果公司转账
 *      到最后一个人的时候,公司余额不够了,这时,所有人的转账都会失败。。。这显然不符合逻辑,我们测试一下先
 * @param a
 * @param b
 * @param nums
 */
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void moreTransact(Account a,List<Account> b,List<Double> nums){
    ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
    AccountService service = applicationContext.getBean(AccountService.class);
    for(int i=0;i<b.size();i++){
        service.transact(a,b.get(i),nums.get(i));
    }
}

事务传播的七种,其实最常用的就两种,REQURED和REQUREDS_NEW,通俗的讲,直接看注释把,这里就不说了。最后的测试结果,开启了REQURED的时候,要么全部成功,要么全部失败,REQUREDS_NEW的时候,则是按transate里面的方法看作原子。

spring事务传播为什么失效了?

这里简简单单几段代码,我却找了很久的bug,那就是spring的传播失效,具体来说是REQUREDS_NEW失效了,这里先说原因

原因

代码语言:javascript
复制
for(int i=0;i<b.size();i++){
    transact(a,b.get(i),nums.get(i));
}

我这里的transact的方法没有交给spring进行管理

思考

说实话我应该冷静分析下,没变肯定是默认的事务传播,如果配置了开启事务还是不行,那就是方法没注入,没给spring管理,我应该冷静下来,思路清晰点

总结

private 和 调用同类的方法 是最常见的两种事务失效的情况。不仅仅是调用自身的类,如果是private方法也会失效

废江博客 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 转载请注明原文链接:ssm整合,事务,aop,事务传播为什么失效???

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 整合ssm
  • spring事务
    • 事务简介
      • spring事务
        • 事务传播
        • spring事务传播为什么失效了?
          • 原因
            • 思考
              • 总结
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档