SSM框架的整合学到尾声了,最后的时候接触到了事务传播机制,有点多,就记下来吧
0.值得注意的坑(SSM事务回滚失效)
在spring-mvc.xml文件中,如果你配置包扫描的时候,是扫描项目下所有的包,比如这样(我的整个项目都在top文件夹下)
那么你的事务机制会出问题,因为spring-mvc是一个子容器,不具有事务功能,而spring-config是顶级父容器,有事务功能,如果你在spring-mvc.xml内扫描了处理事务的service类,会导致事务功能失效
所以,记得要排除掉处理事务的类,只需要把上面的代码改成
1 <context:component-scan base-package="top.**"> 2 <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/> 3 <!--这样设置之后就可以让这个子容器不加载servicer--> 4 </context:component-scan>
然后事务功能就正常了
1.事务的使用(只介绍注释方式)
在负责与数据库交互的方法前加上注释 @Transactional 这样这个方法调用时就会开启一个事务,方法结束时该事务结束
例子:
1 @Transactional //事务注释,涉及到改变数据库的最好都加上 2 public int createStudent(Student student) { 3 studentMapper.insertSelective(student); //接收student并调用studentMapper的insertSelective()方法来写入数据库 4 return 0; 5 }
2.事务注释的属性
在事务注释@Transactional后可以添加括号,里面写上一些属性来改变运行机制,如果不加属性的话,遇到检查错误就会事务回滚
①忽略错误,事务不回滚(有风险,用不用看具体情况)
1 @Transactional(noRollbackFor = RuntimeException.class) //这里的意思是当该事务运行过程中发生RuntimeException错误的时候,事务继续,不回滚
②碰到指定错误也回滚
1 @Transactional(RollbackFor = RuntimeException.class) //遇到指定错误也要回滚,比如你可以自定义一个错误类,设置出现该错误是要回滚
3.事务传播机制
什么是事务传播?我对他的理解就是:在事务与事务之间发生嵌套或者交叉等等情况的时候,来处理他们之间运行的逻辑关系的机制
简单言之,就是负责处理事务之间的关系
用法:和上面一样,在注释后面加个(),再写上对应字段
①默认机制(REQUIRED)
1 @Transactional(propagation = Propagation.REQUIRED)
这是系统默认的机制,特点是:在执行这个事务前,系统会检测在他之前是否已经存在事务,即他是否已经被包含在一个事务里,如果有,则加入该事务来运行,如果没有,则新建一个事务运行.
这种运行逻辑符合95%的情况,平时用的最多的也是这种,反正是默认的,肯定泛用性高啦
②SUPPORTS
1 @Transactional(propagation = Propagation.SUPPORTS)
特点:如果检测到前面有开启中的事务,则加入该事务中,如果前面没有事务,则按照非事务的方式运行下去
③MANDATORY
1 @Transactional(propagation = Propagation.MANDATORY)
特点:该事务前面必须要要有一个开启着的事务;即如果系统在这个事务之前没有检测到开启的事务,会报错. 一般用于不能独立执行,必须要在其他事务中运行的代码,同时也是检查是否有事务包围的好手段
④REQUIRES_NEW
1 @Transactional(propagation = Propagation.REQUIRES_NEW)
特点:运行到这里时,都会新建立一个事务,如果在它之前有开启的事务,则会把它之前的事务暂时挂起暂停,等待它运行完成后,才会继续运行之前的事务
⑤NOT_SUPPORTED
1 @Transactional(propagation = Propagation.NOT_SUPPORTED)
特点:运行到这里时,检查之前有没有开启的事务,有的话就把它挂起暂停,等自己按照非事务的方式运行完成后,再运行前面的事务(与④的区别是它本身不会新建一个事务)
⑥NEVER
1 @Transactional(propagation = Propagation.NEVER)
特点:运行到这里时,系统会检查前面是否有开启着的事务,如果有,会报错,没有则按照非事务的方式执行
⑦NESTED
1 @Transactional(propagation = Propagation.NESTED)
特点:如果前面有开启的事务,则还是会新建一个事务嵌套在其中执行,如果前面没有开启着的事务,则也新建一个事务执行
原文:https://www.cnblogs.com/helldiriver/p/11360540.html