背景
好久没写博客了,今天小写一篇博客,简单写一遍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,事务传播为什么失效???