当前位置:   article > 正文

SpringBoot事务传播机制

springboot事务传播机制

Spring的事务传播机制:是指规定当程序中出现了多个方法出现了嵌套调用的时候,事务是如何进行传递的,事物的传播机制侧重于事务是如何在嵌套调用中传递的,事务的隔离级别侧重于事物之间数据的可见性

1)定义:咱们之前所说的事务,都是针对一个方法的,咱们的Spring事务传播机制,不再是单个的事务了,咱们的Spring事务传播机制定义了包含多个事务的方法相互调用的时候,事务是如何在这些方法中进行传递的;

Spring中多个事务在进行相互调用的时候,它们之间的行为模式是啥样的?

2)比如说A方法加了事务,B方法加了事务,C方法还是加了事务,那咱们的事务是如何进行传递的呢?咱们的A方法里面调用了B方法和C方法,咱们的C方法有异常,AB方法是没有异常的,那我们应该怎们办呢?咱们要进行全局的回滚?那个需要进行回滚呢?

 事务传播机制主要是在一个竖形传播链上面的,一个事务去调用另一个事务,另一个事务又调用了一个事务,那么这个事务如何去执行?如何传递?行为模式是什么样子的?

咱们的事务隔离级别是保证多个并发事务执行的一个可控性的(稳定性),而事务传播机制是保证一个事务在多个调用方法之间的一个可控性的,为什么需要事务的传播机制?这就和为什么需要事务是一样的,就是为了保证程序的稳定性,为了符合我们的一个程序运行预期;

3)事务的传播机制,就是在多个事务进行相互调用的时候,能进行行为控制,能够达到我们预期的效果

4)MYSQL的事务是没有很复杂的,事务只是单纯的在做一件事情,但是事务传播机制,当整个调用链上,有一个程序里面有多个方法的时候,然后,多个方法相互调用的时候,并且这多个方法,都具有事务的时候,这个情况,就是 事务嵌套的问题。
也就是说当程序中出现嵌套事务之后,那么,这些嵌套事务之间的行为模式就是传播机制;

5)隔离性,针对的是不存在事务嵌套 的 前提下。
传播机制,针对是 存在 事务嵌套 的前提下。
从出发点来看,它们就不一样;

隔离性多个事务并发执行,但不会存在嵌套事务的问题,就好像每个人都在自己的跑道上奔跑,互不干扰。

传播机制在一个调用链上,多个方法里面有多个事务,而这多个事务在相互调用的时候 ,使用的行为模式。

传播机制就是:
多个事务都在 “ 一条线上 ” ,然后,以什么样的行为(方式)去进行事务传播(调用事务)

事务的隔离性:
多个事务不在 “ 一条线上 ” 的,走着各自的路线,互不影响

Spring中事务挂起的含义是,需要新事务时
将现有的connection1保存起来(它还有尚未提交的事务)
然后创建connection2,connection2提交、回滚、关闭完毕后
再把connection1取出来,完成提交、回滚、关闭等动作
保存connection1的动作称之为事务挂起

支持当前事务:要有房子的

不支持当前事务:不需要有房子的

以非事务的方式继续运行:租房子

男朋友:方法

女朋友:方法

Spring的事务传播机制:

Propagation的意思就是传播

上面三种都是支持当前事务的,下面三种如果有事务,执行方式相同,如果没有事务,执行方式不同

1)Propagation.REQUIRED:必须的,是一个默认的传播机制,它表示如果当前存在事务,那么就直接加入到事务里面,如果当前没有事务,就自己进行创建一个新的事务,如果调用链上面有一个出现了问题,那么就全部进行回滚;

类似于说女朋友买房,男朋友有房子女朋友就住进去,男朋友没房子,女朋友自己新建一个房子,自己住;

2)Propagation.SUPPORTS:如果说当前存在事务,那么直接加入到该事务,如果当前没有事务,则以⾮事务的⽅式继续运⾏;

如果男朋友有房子,那么就直接住进去,男朋友没有房子也没关系,女朋友自己租房子也行

3)Propagation.MANDATORY:(mandatory中文是强制性)比如说A方法调用B方法的时候,我们的两个方法必须都要有事务,就将他们合成一个新的事务,反之就会抛出异常,如果当前存在事务,那么就加入到该事务,如果当前没有事务,那么直接抛出异常;

如果男朋友有房子好说,直接住进去,如果男朋友没房子,直接闹掰,直接分手,直接崩了

上面的情况都是支持当前事务的,也就是说如果当前存在事务,那么上面三种的运行结果都是一样的,如果不存在事务,那么运行结果就会不相同;

4)Progagation.REQUIRES_NEW:表示创建一个新的事务,如果说当前存在事务,则会把当前事务进行挂起,也就是说无论外部方法是否开启事务,Progagation.REQUIRES_NEW修饰的内部方法会开启自己的事务,况且开启的事务之间会相互独立,互不干扰,各个方法之间的事务是相互独立的,是互不干扰的,不会进行全局的事务回滚,自己回滚自己的;

女朋友不管男朋友在西安有没有房子,你有房子我也不住,必须要买一个单独新的房子,女朋友自己单独开启一个新的事务;

5)Propagation.NEVER:表示如果调用链上面的任意一个方法出现了事务,那么就会直接抛出异常

就是你男朋友有房子,还要还房贷,直接分手,没房子非常好,不想住房子,就想住大街;

6) Propagation.NOT_SUPPORTED
⾮事务⽅式运⾏,如果当前存在事务,则把当前事务挂起,不会以事务的方式运行

不管男朋友有没有卖房子,女朋友自己都要租房子,就是以非事务的方式来运行;

上面三种是不支持当前事务,不管有没有房子都不住;

7)Propagation.NESTED
如果当前存在事务,则创建⼀个事务作为当前事务的嵌套事务来运⾏;
如果当前没有事务,自己创建一个新事务,则该取值等价于 PROPAGATION_REQUIRED,

对于嵌套事务来说A方法调用B方法和C方法,B和C都是开启的是嵌套事务,那么B或者C在进行回滚的时候只会回滚自己的,也就是说嵌套事务发生回滚只是会影响自己的业务逻辑而不是全局,要注意在嵌套事务中可能出现异常的部分要手动处理进行回滚,不能让异常抛出,否则会被全局代理感知到造成全局事务的整体回滚,TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

加入事务和嵌套事务的区别: 

1)如果整个调用链上面的事务全部执行成功了,那么两者的最终结果是相同的

2)如果说事务执行到一半失败了,那么加入事务会将整个事务全部进行回滚,嵌套事务会进行局部回滚,不会影响到上一个方法中执行的结果,不会影响之前的事务执行的

对于嵌套事务来说,之所以嵌套事务可以实现部分事务的回滚,是因为事务中有一个保存点的概念,嵌套事务进入之后相当于是新建了一个保存点,而回滚的时候可以回滚到保存点,每一个事务执行完成之后都会有一个保存点,因此之前的事务是不会受影响的,相当于是临时工,一旦临时工出问题,直接开除,不影响原有的事务,嵌套事务是一个外部事务的一个子事务,是一个外部事务的一个组成部分,当嵌套事务发生异常,而回滚,则会回复到嵌套事务的执行前的状态;

加入事务,整个事务都会回滚,是会影响原来的事务的,加入事务没有设置保存点;

事务的隔离级别和事务的传播机制:

1)事务的隔离级别描述的是多个事务同时执行时候的某一种行为,是事务四大特性中的隔离性的一种特殊体现,使用事务的隔离级别可以进行控制并发事务同时执行的某种行为,也就是说多个事务共同操作数据库

2)事务的隔离级别指的是纵向事务并发调用的行为模式

3)而事务的传播机制指的是横向事务传递的时候的行为模式,包含了多个事务相互调用的时候事务的传播行为

过滤器:设置字符编码,防盗链

使用过滤器使用的是Servlet3.0提供的@WebFilter注解,配置过滤的url规则,然后在实现@WebFilter接口,重写里面的doFilter方法:

  1. package com.example.demo;
  2. import org.springframework.stereotype.Component;
  3. import javax.servlet.*;
  4. import javax.servlet.annotation.WebFilter;
  5. import java.io.IOException;
  6. @WebFilter(urlPatterns = "/Java100")
  7. @Component
  8. public class Configuration implements Filter {
  9. @Override
  10. public void init(FilterConfig filterConfig) throws ServletException {
  11. System.out.println("执行过滤器前置方法");
  12. }
  13. @Override
  14. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
  15. System.out.println("开始执行过滤器");
  16. filterChain.doFilter(servletRequest,servletResponse);
  17. System.out.println("执行完过滤器");
  18. }
  19. @Override
  20. public void destroy() {
  21. System.out.println("执行过滤器后置方法");
  22. }
  23. }

1)void init()这个是Spring容器启动的时候会被调用,整个程序运行期间只会调用一次,用于实现Filter的初始化

2)在doFilter方法执行具体的流程

3)我们在destory完成Filter销毁之前完成的工作

  1. package com.example.demo;
  2. import org.springframework.stereotype.Component;
  3. import javax.servlet.*;
  4. import javax.servlet.annotation.WebFilter;
  5. import javax.servlet.http.HttpServletRequest;
  6. import javax.servlet.http.HttpServletResponse;
  7. import javax.servlet.http.HttpSession;
  8. import java.io.IOException;
  9. @WebFilter(urlPatterns = "/Java100")
  10. @Component
  11. public class Configuration implements Filter {
  12. @Override
  13. public void init(FilterConfig filterConfig) throws ServletException {
  14. System.out.println("执行过滤器前置方法");
  15. }
  16. @Override
  17. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
  18. HttpServletRequest request=(HttpServletRequest)servletRequest;
  19. HttpServletResponse response=(HttpServletResponse)servletResponse;
  20. HttpSession httpSession= request.getSession();
  21. if(httpSession==null){
  22. filterChain.doFilter(servletRequest,servletResponse);
  23. }else{
  24. response.sendRedirect("http://www.baidu.com");
  25. }
  26. }
  27. @Override
  28. public void destroy() {
  29. System.out.println("执行过滤器后置方法");
  30. }
  31. }

拦截器和过滤器的区别

1)出身不同:过滤器是来源于Servlet,通过这个过滤器是导入Servlet相关的jar包,但是拦截器是来源于Spring框架,导入拦截器是导入的是有关于Spring相关的包

2)触发时机不同:请求进入容器>进入过滤器>进入到Servlet>进入到拦截器>执行控制器,也就是说过滤器会先执行,然后才会执行拦截器,最后才会执行真正调用的方法

3)过滤器是通过方法回调实现的,但是拦截器是通过动态代理来进行实现的

4)过滤器必须在Web项目中进行使用,但是拦截器可以应用于任何项目

5)拦截器通常使用作于业务逻辑的的判断,但是过滤器通常用于字符编码设置,字符集设置

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/387157
推荐阅读
相关标签
  

闽ICP备14008679号