介绍一下spring的事务管理,spring的事务管理是如何实现的

  介绍一下spring的事务管理,spring的事务管理是如何实现的

  00-1010什么是事务Spring事务配置Spring事务传播行为1。propagation _ required2传播_支持3。传播_需求_新的声明性事务无效

  00-1010事务是由数据库上的若干操作组成的单元。

  我们在开发企业应用的时候,对于业务人员来说一个操作其实就是数据读写多步操作的组合。在数据操作的顺序执行过程中,任何一步操作都可能出现异常,从而导致后续操作的失败。此时由于业务逻辑还没有正确完成,之前成功操作的数据是不可靠的,这种情况下就需要回滚。

  事务的作用是保证用户的每一个操作都是可靠的,事务中的每一个操作都必须成功执行。只要有异常,就会回到事务未被操作的状态,这些操作要么完成,要么取消,以保证数据满足一致性的要求。

  怎么理解呢?

  比如3360A现在要转钱给B,那么转钱有多少种方法呢?两个:方法,13360a减钱,23360b增钱。

  如果在方法A成功执行后,方法B的执行出现异常,意味着A的钱被扣了但是B的钱没有被加,那么这样的行为肯定是不允许的,所以我们引入事务的概念,一般是针对数据库的。

  

目录

Spring事务管理分为程序化事务和声明性事务。

 

  项目中很少使用程序化交易。这个公式需要注入一个事务管理对象TransactionTemplate,然后当我们需要在代码中提交或回滚事务时,我们可以自己编写代码来实现它。

  声明式事务管理是基于AOP的,其本质是在方法前后进行拦截,所以声明式事务是在方法层面。

  为什么是基于AOP?因为这是我们通过xml文件在配置中所做的。

  AOP : config AOP : pointcut expression= execution(* com . ff . spring . service . userservice . *(.)) id= all method /AOP : advisor advice-ref= tx advice pointcut-ref= all method //AOP : config直接帮助我们基于注释省略这个过程,更加方便。

  这里主要介绍声明式事务。

  首先,在db.xml中配置spring事务管理类

  !-Configure spring Transaction Management Class-bean ID= sourceTransactionManager Class= org . spring framework . JDBC . data source . data source Transaction manager property name= data source Ref= druid data source //bean这里我们直接介绍基于注释的spring事务管理。

  打开批注扫描

  !-开启批注事务管理-tx3360批注驱动的事务-manager= sourcetransactionmanager /我们使用类似@Transactiona的批注标签来声明事务,可以作用于方法,表示该方法支持事务,也可以作用于类,表示该类中的所有方法都支持事务。

  公共类UserDao { @ Autowired JDBC template JDBC template;@Transactional(传播=传播。必选)public void save user(){ JDBC template . update( insert into admin(account,pass_word,sex)值(?)、李、 111 、男);int I=108/0;//异常JDBC template . update( insert into admin(account,pass _ word,sex)值(?)、 qw 、 111 、男);}}在上面的代码中,虽然成功执行了第一条sql语句,但是后面出现了异常,所以这个方法的事务没有提交,数据也不会提交到数据库。

  

什么是事务

 

  Spring事务传播行为 即然是传播,那么至少有两个东西,才可以发生传播。单体不存在传播这个行为。事务传播行为(propagation behavior)指的就是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行。事务传播行为是 Spring 框架独有的事务增强特性,他不属于的事务实际提供方数据库行为.

   是不是有点懵, 说啥呢这是, 接着来解释

   试想 , 有两个方法 A 和 B , 它们都有事务, 那么我在 A 方法中去调用 B 方法, 那么B方法此时

  应该怎样去执行呢? 是将B 方法加入到 A 方法组成一个事务,还是它们都是一个独立的事务呢 ?

   Spring定义了 7种 事务传播行为, 我们下面主要介绍其中三种,都会举例说明

   传播行为一般是对于B方法(被调用的方法而言的)

  

 

  

1. PROPAGATION_REQUIRED

指定的方法必须在事务内执行,若当前存在事务,加入到当前事务中,若当前没有事务,则创建一个新事务,这种传播行为是最常见的,也是 spring 默认的传播行为

 

   A 方法调用 B方法(PROPAGATION_REQUIRED) , 如果A方法是存在事务的, 那么直接将B方

  法加入到 A事务中,组成一个事务. 如果 A 方法是没有事务的, 那么B就是一个单独的事务

   这么说可能有点绕 , 我们再次请出李雷, 算了, 这次就放过李雷, 换成张三吧

   就是说呢 , 我和李雷现在都要去吃饭, 然后我说呢,李雷咱俩一起吧(A调用B,我叫李雷去吃饭) ,不出意外的话(事务顺利执行提交), 我们两吃饭作为一个整体, 最终都吃了饭(AB都存在事务就作为一个整体事务) , 但是还有一种情况, 我叫李雷去吃饭, 但是我却没有去(A调用B, 但是A没有事务),那么这时候李雷肯定单独去吃饭(B单独开启一个事务)

  

@Transactional(propagation = Propagation.REQUIRED) public void saveDept(){ //A调用B deptDao.saveDept(); commonService.saveLog(); //B }
@Transactional(propagation = Propagation.REQUIRED) public void saveLog(){ commonDao.saveLog(); int a = 10/0; //异常 }

此时 A 调用 B , 它们都有事务, B中出了异常, 那么此时AB最终都不会去和数据库交互

 

  

//@Transactional(propagation = Propagation.REQUIRED) public void saveDept(){ //A调用B deptDao.saveDept(); commonService.saveLog(); //B }
@Transactional(propagation = Propagation.REQUIRED) public void saveLog(){ commonDao.saveLog(); int a = 10/0; //异常 }

第二种方式 , 我们将异常加到A 中, 注释掉注解(取消A的事务), 那么此时B是单独的一个事务, B里面出了异常, 不会去和数据库交互, 则A会去和数据库交互

 

  

 

  

2. PROPAGATION_SUPPORTS

支持当前事务,如果当前没有事务,就以非事务方式执行

 

   A方法调用B方法(PROPAGATION_SUPPORTS), 如果A是存在事务的,那么直接将B方

  法加入到 A事务中,组成一个事务. 如果 A 没有事务, 那么B也没有事务

   我叫李雷去吃饭 , 如果我一定要去吃饭(A调用B), 那么最终我吃饭和李雷吃饭就总共作为一个事务,就和上面第一个例子是一样的, 作为整体的一个事务. 但是第二种情况就是, 我虽然叫了李雷去吃饭, 但是我最终没有去(A没有事务) , 这时候李雷说, 那我也不去吃饭了(B也没有事务)

  

@Transactional(propagation = Propagation.REQUIRED) public void saveDept(){ //A调用B deptDao.saveDept(); commonService.saveLog(); //B }
@Transactional(propagation = Propagation.SUPPORTS) public void saveLog(){ commonDao.saveLog(); int a = 10/0; //异常 }

此时 A调用 B , AB都有事务, 那么B 中出现异常, 最终都不会和数据库交互,就和上述第一种情况

 

  一样

  

//@Transactional(propagation = Propagation.REQUIRED) public void saveDept(){ //A调用B deptDao.saveDept(); commonService.saveLog(); //B }

取消掉A 的事务 , 那么此时B 会以非事务执行 , 这时候AB都会和数据库去交互,因为非事务

 

  

 

  

3. PROPAGATION_REQUIRES_NEW

总是新建一个事务,如果当前存在事务,把当前事务挂起,直到新建的事务结束。

 

   A方法调用B方法(PROPAGATION_REQUIRES_NEW), 如果A存在事务, 那么B此时会先把A事务挂起, 然后为自己新建一个事务, 先执行完B事务, 才会去执行 A 事务 . 如果A 没有事务, 那么B自己单独新建一个事务执行

   这里就是, 我虽然叫李雷去吃饭(A调用B) , 李雷都会先自己去吃饭, 不等我(B自己新建一个事务, A有事务先将A挂起)

  

@Transactional(propagation = Propagation.REQUIRED) public void saveDept(){ //A调用B deptDao.saveDept(); commonService.saveLog(); //B }
@Transactional(propagation = Propagation.REQUIRES_NEW) public void saveLog(){ commonDao.saveLog(); int a = 10/0; //异常 }

A 调用 B , A支持事务 , 此时B将A事务挂起, 单独开启一个事务,里面出现异常,此时AB都不会和数据库交互

 

  

//@Transactional(propagation = Propagation.REQUIRED) public void saveDept(){ //A调用B deptDao.saveDept(); commonService.saveLog(); //B }

取消A的事务, 但此时B事务是独立的, 出现异常, 所以B不会和数据库交互,但是A和数据库交互

 

  

 

  

声明式事务失效

事务也是会失效的 , 失效有以下几种情况

 

  1.@Transactional 应用在非 public 修饰的方法上

  2.@Transactional 注解属性 propagation 设置错误

  3.同一个类中方法调用,导致@Transactional 失效

  4.异常被 catch 捕获导致@Transactional 失效

  5.数据库引擎不支持事务

  非public修饰导致权限错误, 事务失效, propagation设置参数错误导致事务失效

  同类下方法调用也会导致事务失效

  catch如果捕获了异常, 就相当于程序没有异常,这时事务也会失效

  最后就是数据库引擎不支持, mysql中只有InnoDB引擎是支持事务的

  结语

   关于Spring 事务管理就先说到这 , 后面介绍SpringMVC 与 ssm 框架, 谢谢,爱你们

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • spring编程式事务处理,spring编程事务
  • spring编程式事务处理,spring编程事务,详解Spring学习之编程式事务管理
  • spring的核心功能模块有几个,列举一些重要的spring模块
  • spring的核心功能模块有几个,列举一些重要的spring模块,七个Spring核心模块详解
  • spring注解和springmvc的注解,SpringMVC常用注解
  • spring注解和springmvc的注解,SpringMVC常用注解,详解springmvc常用5种注解
  • spring实现ioc的四种方法,spring的ioc的三种实现方式
  • spring实现ioc的四种方法,spring的ioc的三种实现方式,简单实现Spring的IOC原理详解
  • spring事务失效问题分析及解决方案怎么做,spring 事务失效情况
  • spring事务失效问题分析及解决方案怎么做,spring 事务失效情况,Spring事务失效问题分析及解决方案
  • spring5.0新特性,spring4新特性
  • spring5.0新特性,spring4新特性,spring5新特性全面介绍
  • spring ioc以及aop原理,springmvc aop原理
  • spring ioc以及aop原理,springmvc aop原理,深入浅析Spring 的aop实现原理
  • Spring cloud网关,spring cloud zuul作用
  • 留言与评论(共有 条评论)
       
    验证码: