Spring事务与事务传播机制

article/2025/9/20 8:01:19

目录

1.事务的基本概念

2.Spring事务的实现

3.事务隔离级别

4.事务传播机制


1.事务的基本概念

关于事务的一些基础概念我已经在MYSQL中讲解过了,有不了解的可以移步至此篇文章:
MySQL基础——数据库索引与事务_invictusQAQ的博客-CSDN博客

2.Spring事务的实现

Spring 中的事务操作分为两类:

1. 编程式事务(⼿动写代码操作事务)。

2. 声明式事务(利⽤注解⾃动开启和提交事务)。

在我们讲解他们如何使用之前,我们先来回顾一下MYSQL中事务的使用

2.1 回顾MYSQL中事务的使用

-- 开启事务
start transaction;
-- 业务执⾏
-- 提交事务
commit;
-- 回滚事务
rollback;

 2.2 Spring 编程式事务

当然此种方法较为麻烦,而且实际也很少使用,所以我们仅做了解

Spring ⼿动操作事务和上⾯ MySQL 操作事务类似,它也是有 3 个重要操作步骤:

1.开启事务(获取事务)。

2.提交事务。

3.回滚事务。

SpringBoot 内置了两个对象,DataSourceTransactionManager ⽤来获取事务(开启事务)、提交或 回滚事务的,而TransactionDefinition 是事务的属性,在获取事务的时候需要将 TransactionDefinition 传递进去从而获得⼀个事务 TransactionStatus,实现代码如下: 

    @Autowiredprivate DataSourceTransactionManager dataSourceTransactionManager;@Autowiredprivate TransactionDefinition transactionDefinition;@Autowiredprivate UserService userService;@RequestMapping("/add")public int add(UserInfo userInfo){//参数合法性判断if(userInfo==null||!StringUtils.hasLength(userInfo.getUsername())|| !StringUtils.hasLength(userInfo.getPassword())) return 0;// 开启事务(获取事务)TransactionStatus transactionStatus=dataSourceTransactionManager.getTransaction(transactionDefinition);int result= userService.add(userInfo);System.out.println("add 受影响的行数:" + result);//回滚事务dataSourceTransactionManager.rollback(transactionStatus);//或者提交事务//dataSourceTransactionManager.commit(transactionStatus);return result;}

2.3 Spring 声明式事务(自动)

声明式事务的实现很简单,只需要在需要的⽅法上添加 @Transactional 注解就可以实现了,无需手动 开启事务和提交事务,进入方法时⾃动开启事务,方法执行完会⾃动提交事务,如果中途发生了没有处 理的异常会自动回滚事务,具体实现代码如下:

  // 使用声明式事务@Transactional//@Transactional内部可以设置隔离级别等其他属性@RequestMapping("/add2")public int add2(UserInfo userInfo){if(userInfo==null||!StringUtils.hasLength(userInfo.getUsername())|| !StringUtils.hasLength(userInfo.getPassword())) return 0;// 开启事务(获取事务)int result= userService.add(userInfo);System.out.println("add 受影响的行数:" + result);return result;}

还是之前的实现添加用户的功能,但是代码却简洁了不少

2.3.1 @Transactional 作用范围 

@Transactional 可以用来修饰方法或类

修饰方法时:需要注意只能应用到 public ⽅法上,否则不⽣效。推荐此种⽤法。

修饰类时:表明该注解对该类中所有的 public ⽅法都⽣效

2.3.2 @Transactional 参数说明 

前面我们提到@Transactional是可以设置多种参数的,比如下面:

 而它们的具体含义如下,大家可以根据实际情况灵活去选择

 2.3.3 注意事项

前面我们提到了@Transactional在事务内部出现异常时是会自动回滚的,这个也可以配合我们前面提到了@Transactional的rollbackFor等和异常处理相关的参数使用。但是假如我们使用了try-catch语句去处理了可能出现异常的代码段,那么此时即使发生了异常事务也不会回滚。

例如下面的代码,它由于使用了try-catch语句捕获异常,所以此时@Transactional就不会再去处理该异常,自然也就不会对事务进行回滚。因为Spring认为你已经使用了try-catch使用他就不会再去干涉了。

@RestController
public class UserController {@Resourceprivate UserService userService;@RequestMapping("/save")@Transactionalpublic Object save(User user) {// 插⼊数据库int result = userService.save(user);try {// 执⾏了异常代码(0不能做除数)int i = 10 / 0;} catch (Exception e) {System.out.println(e.getMessage());}return result;}
}

那么我们如何让事务在这种情况下依然能够实现自动回滚呢? 

解决方案1:对于捕获的异常,事务是会⾃动回滚的,因此解决方案1就是可以将异常重新抛出,具体实现如下:

    @RequestMapping("/save")@Transactional(isolation = Isolation.SERIALIZABLE)public Object save(User user) {// 插⼊数据库int result = userService.save(user);try {// 执⾏了异常代码(0不能做除数)int i = 10 / 0;} catch (Exception e) {System.out.println(e.getMessage());// 将异常重新抛出去throw e;}return result;}

当然此种方法将异常捕获后又重新抛出,似乎很奇怪,所以还有解决方法2。

解决方案2:⼿动回滚事务,在方法中使用 TransactionAspectSupport.currentTransactionStatus() 可以得到当前的事务,然后设置回滚方法 setRollbackOnly 就可以实现回滚了,具体实现代码如下:

    @RequestMapping("/save")@Transactional(isolation = Isolation.SERIALIZABLE)public Object save(User user) {// 插⼊数据库int result = userService.save(user);try {// 执⾏了异常代码(0不能做除数)int i = 10 / 0;} catch (Exception e) {System.out.println(e.getMessage());// ⼿动回滚事务TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();}return result;}

2.3.4 @Transactional 工作原理

@Transactional 是基于 AOP 实现的,AOP 又是使用动态代理实现的。如果⽬标对象实现了接口,默认情况下会采用 JDK 的动态代理,如果目标对象没有实现了接口,会使用 CGLIB 动态代理。 @Transactional 在开始执行业务之前,通过代理先开启事务,在执⾏成功之后再提交事务。如果中途 遇到的异常,则回滚事务。

@Transactional 具体执行细节如下图所示:

 3.事务隔离级别

 3.1 事务特性回顾

1.原子性:最核心的特性,即逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部失败

2.一致性:保证数据一致,没有纰漏

3.持久性:只要事务执行成功,造成的修改就是可持久化保存的(保存在磁盘/硬盘中)

4.隔离性:描述多个事务并行执行所发生的情况

而这 4 种特性中,只有隔离性(隔离级别)是可以设置的。 

为什么要设置事务的隔离级别?

设置事务的隔离级别是⽤来保障多个并发事务执⾏更可控,更符合操作者预期的。

其实再说得通俗一点就是我们可以通过设置事务的隔离级别来控制脏读,不可重复读,幻读的现象发生与否

3.2 Spring 中设置事务隔离级别 

Spring 中事务隔离级别可以通过 @Transactional 中的 isolation 属性进⾏设置,具体操作如下图所 示:

3.2.1 MySQL 事务隔离级别 

在讲解Spring中的事务隔离级别之前我们先来回顾一下MYSQL中的事务隔离级别。

1. READ UNCOMMITTED:读未提交,也叫未提交读,该隔离级别的事务可以看到其他事务中未提 交的数据。该隔离级别因为可以读取到其他事务中未提交的数据,⽽未提交的数据可能会发⽣回滚,因此我们把该级别读取到的数据称之为脏数据,把这个问题称之为脏读。

2. READ COMMITTED:读已提交,也叫提交读,该隔离级别的事务能读取到已经提交事务的数据, 因此它不会有脏读问题。但由于在事务的执行中可以读取到其他事务提交的结果,所以在不同时间 的相同 SQL 查询中,可能会得到不同的结果,这种现象叫做不可重复读。

3. REPEATABLE READ:可重复读,是 MySQL 的默认事务隔离级别,它能确保同⼀事务多次查询 的结果⼀致。但也会有新的问题,比如此级别的事务正在执⾏时,另⼀个事务成功的插⼊或者删除了某条数据,此时再去查询数据会发现突然多了或者少了部分数据,好像出现了幻觉,这就叫幻读 (Phantom Read)。

4. SERIALIZABLE:序列化,事务最⾼隔离级别,它会强制事务排序,使之不会发⽣冲突,从而解决 了脏读、不可重复读和幻读问题,但因为执行效率低,所以真正使⽤的场景并不多。

 这里我们重点区分一下不可重复读与幻读的区别:

不可重复读强调的重点在于修改(update)而幻读强调的重点在于插入和删除(insert/delete)

 

3.2.2 Spring 事务隔离级别 

 Spring 中事务隔离级别包含以下 5 种,仅仅只比MYSQL多了一种DEFAULT级别:

1. Isolation.DEFAULT:以连接的数据库的事务隔离级别为主

2. Isolation.READ_UNCOMMITTED:读未提交,可以读取到未提交的事务,存在脏读

3. Isolation.READ_COMMITTED:读已提交,只能读取到已经提交的事务,解决了脏读,存在不可重 复读

4. Isolation.REPEATABLE_READ:可重复读,解决了不可重复读,但存在幻读(MySQL默认级 别)

5. Isolation.SERIALIZABLE:串行化,可以解决所有并发问题,但性能太低

注意事项:

 1.当Spring设置了事务隔离级别和连接的数据库(MYSQL)隔离级别冲突时,以Spring的隔离级别为准

2.Spring事务中的事务隔离级别机制的实现是依靠连接数据库支持的隔离级别为基础

4.Spring事务传播机制

4.1 什么是事务传播机制

Spring 事务传播机制定义了多个包含了事务的⽅法,相互调用时,事务是如何在这些⽅法间进⾏传递的。

4.2 为什么需要事务传播机制

事务隔离级别是保证多个并发事务执行的可控性的(稳定性的),而事务传播机制是保证⼀个事务在多个调⽤⽅法间的可控性的(稳定性的)。

直观的去理解就是事务隔离级别是保证事务并行可控性,类似于下图:

 而事务传播机制是解决了事务调用链的可控性,类似于下图:

 4.3 事务的传播机制有哪些

Spring 事务传播机制包含以下 7 种:

1. Propagation.REQUIRED:默认的事务传播级别,它表示如果当前存在事务,则加⼊该事务;如果当前没有事务,则创建⼀个新的事务。

2. Propagation.SUPPORTS:如果当前存在事务,则加⼊该事务;如果当前没有事务,则以⾮事务的方式继续运行。

3. Propagation.MANDATORY:(mandatory:强制性)如果当前存在事务,则加⼊该事务;如果当 前没有事务,则抛出异常。

4. Propagation.REQUIRES_NEW:表示创建⼀个新的事务,如果当前存在事务,则把当前事务挂 起。也就是说不管外方法是否开启事务,Propagation.REQUIRES_NEW 修饰的内部⽅法会新开 启⾃⼰的事务,且开启的事务相互独立,互不干扰。

5. Propagation.NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。

6. Propagation.NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。

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


我们可以通过将其分类来帮助我们记忆 

 

 

4.4 Spring 事务传播机制使用和各种场景演示 

首先我们搭建测试所需环境,此处我们依然选择模拟ssm项目结构,结构如下:

 我们程序的执行逻辑大概如下:

 UserMapper:

package com.example.springtransactiondemo.mapper;import com.example.springtransactiondemo.model.UserInfo;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface UserMapper {public int add(UserInfo userInfo);
}

LogMapper:

package com.example.springtransactiondemo.mapper;import com.example.springtransactiondemo.model.LogInfo;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface LogMapper {public int add(LogInfo logInfo);
}

UserService:

package com.example.springtransactiondemo.service;import com.example.springtransactiondemo.mapper.UserMapper;
import com.example.springtransactiondemo.model.UserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;@Service
public class UserService {@Autowiredprivate UserMapper userMapper;@Transactionalpublic int add(UserInfo userInfo){int result= userMapper.add(userInfo);return result;}
}

LogService:

package com.example.springtransactiondemo.service;import com.example.springtransactiondemo.mapper.LogMapper;
import com.example.springtransactiondemo.model.LogInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;@Service
public class LogService {@Autowiredprivate LogMapper logMapper;@Transactionalpublic int add(LogInfo logInfo) {int result = logMapper.add(logInfo);System.out.println("添加日志结果:" + result);int num=1/0;//模拟发生异常的情况return result;}
}

而为了测试我们spring的事务传播机制,最终我们UserController的执行逻辑如下:

 所以我们得到了我们测试所需的UserController代码如下:

package com.example.springtransactiondemo.controller;import com.example.springtransactiondemo.model.LogInfo;
import com.example.springtransactiondemo.model.UserInfo;
import com.example.springtransactiondemo.service.LogService;
import com.example.springtransactiondemo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.sql.DataSourceDefinition;@RestController
public class UserController {@Autowiredprivate UserService userService;@Autowiredprivate LogService logService;@Transactional@RequestMapping("/add")public int add3(UserInfo userInfo){//参数合法性校验if (userInfo == null ||!StringUtils.hasLength(userInfo.getUsername()) ||!StringUtils.hasLength(userInfo.getPassword())) {return 0;}int userResult=userService.add(userInfo);System.out.println("添加用户:" + userResult);LogInfo logInfo=new LogInfo();logInfo.setName("添加用户");logInfo.setDesc("添加用户结果:" + userResult);int logResult= logService.add(logInfo);return userResult;}
}

 4.4.1 支持当前事务(REQUIRED)

以下代码实现中,先开启事务先成功插⼊⼀条⽤户数据,然后再执行日志报错,而在日志报错是发⽣了 异常,观察 propagation = Propagation.REQUIRED 的执行结果。

这里的测试代码我们在上面已经放出来了,就不在赘述。而得到的结果是程序报错,数据库没有插入任何数据。

执行流程描述:

1. UserService 中的保存⽅法正常执⾏完成。

2. LogService 保存日志程序报错,因为使⽤的是 Controller 中的事务,所以整个事务回滚。 3. 数据库中没有插入任何数据,也就是步骤 1 中的用户插⼊⽅法也回滚了。 

4.4.2 不支持当前事务(REQUIRES_NEW) 

UserController 类中的代码不变,将添加用户和添加日志的方法修改为 REQUIRES_NEW 不⽀持当前事务,重新创建事务,观察执行结果:

此处我们的LogService依然模拟抛出异常,但此次用户数据插入成功,日志数据插入失败被回滚了。说明REQUIRES_NEW创建的两个新事务是独立的,不会互相影响。

4.4.3 NESTED 嵌套事务 

UserController 类中的代码不变,将添加用户和添加日志的方法修改为 Propagation.NESTED 嵌套事务,重新创建事务,观察执行结果:

此处我们的LogService依然模拟抛出异常,此次用户数据插入成功,日志数据插入失败被回滚了。说明嵌套事务是可以部分回滚的,没有因为嵌套事务抛出异常而导致同一层的嵌套事务以及外层的事务报错回滚。

4.5 事务传播机制的相关注意事项 

4.5.1 REQUIRED / REQUIRES_NEW / NESTED的区别

REQUIRED会加入当前的事务,此时可以看作两个事务融为一体,其中一个事务报错另一个也会一起陪它回滚。而REQUIRES_NEW则是创建了新的事务,和别的事务没有关系,所以同层次的另一个事务报错不影响该事务继续执行。而NESTED嵌套事务 进入之后相当于新建了⼀个保存点,滚回时只回滚到当前保存点,因此之前的事务是不受影响的,所以可以实现部分回滚。

4.5.2 有关事务自调用问题  

以下部分内容来自一个@Transactional哪里来这么多坑?_Foo.的博客-CSDN博客

部分内容根据自己的理解进行了修改 

@Service
public class DmzService {public void saveAB(A a, B b) {saveA(a);saveB(b);}@Transactionalpublic void saveA(A a) {dao.saveA(a);}@Transactionalpublic void saveB(B b){dao.saveB(a);}
}

上面三个方法都在同一个类DmzService中,其中saveAB方法中调用了本类中的saveAsaveB方法,这就是自调用。在上面的例子中saveAsaveB上的事务会失效

那么自调用为什么会导致事务失效呢?我们知道Spring中事务的实现是依赖于AOP的,当容器在创建dmzService这个Bean时,发现这个类中存在了被@Transactional标注的方法(修饰符为public)那么就需要为这个类创建一个代理对象并放入到容器中,创建的代理对象等价于下面这个类:

public class DmzServiceProxy {private DmzService dmzService;public DmzServiceProxy(DmzService dmzService) {this.dmzService = dmzService;}public void saveAB(A a, B b) {dmzService.saveAB(a, b);}public void saveA(A a) {try {// 开启事务startTransaction();dmzService.saveA(a);} catch (Exception e) {// 出现异常回滚事务rollbackTransaction();}// 提交事务commitTransaction();}public void saveB(B b) {try {// 开启事务startTransaction();dmzService.saveB(b);} catch (Exception e) {// 出现异常回滚事务rollbackTransaction();}// 提交事务commitTransaction();}
}

简单的说就是我们理想情况下应该是先通过代理类然后采取调用目标方法,但实际上我们会通过this来直接调用目标方法,也就是说此时我们没有经过代理类而是直接通过this来调用,此时就导致了代理失效的问题。

常见的自调用导致的事务失效还有一个例子,如下:

@Service
public class DmzService {@Transactionalpublic void save(A a, B b) {saveB(b);}@Transactional(propagation = Propagation.REQUIRES_NEW)public void saveB(B b){dao.saveB(a);}
}

 当我们调用save方法时,我们预期的执行流程是这样的:

 但还是由于this的存在,所以我们实际上还是会不经过代理去直接通过this调用目标方法导致事务失效。

4.5.3 关于REQUIRES_NEW的补充

REQUIRES_NEW官方文档解释:
Create a new transaction, and suspend the current transaction if one exists.
意思是,创建一个新事务,如果当前存在事务,将这个事务挂起。也就是说如果当前存在事务,那么将当前的事务挂起,并开启一个新事务去执行REQUIRES_NEW标志的方法。

但是当它在嵌套调用的时候有几点我们是需要注意的:

1.标志REQUIRES_NEW会新开启事务,外层事务不会影响内部事务的提交/回滚
2.标志REQUIRES_NEW的内部事务的异常,会影响外部事务的回滚 

我们也可以结合NESTED一起来记忆

REQUIRES_NEW 和 NESTED ,前者是内层异常影响外层,外层不影响内层;后者正好相反,内层加try catch后 异常不影响外层,外层会影响内层。 

4.5.4 REQUIRES与REQUIRES_NEW嵌套场景简单总结 

1.同类中:无事务方法 嵌套 事务方法 ,事务不生效,因spring 中事务基于代理实现。详细原理请见4.5.2

2.同类中:REQUIRES 嵌套 REQUIRES_NEW ,REQUIRES_NEW不生效,加入到REQUIRES事务中,原理同上。

3.同类中:REQUIRES(1) 嵌套 REQUIRES (2),其实REQUIRES(2)事务注解也是不生效的,只是加入到REQUIRES(1)事务中,看起来REQUIRES(2)事务注解是生效的,原理同上。

4.同类中:REQUIRES(1) 嵌套 REQUIRES或REQUIRES_NEW (2),(1) 中 try {(2)}catch{e.printStackTrace();} , 2异常,1与2都不会回滚,因为2实际无事务,异常也被1 catch,故都不回滚。

5.不同类中:REQUIRES 嵌套 REQUIRES_NEW,情况1:REQUIRES无异常,REQUIRES_NEW发生异常,REQUIRES与REQUIRES_NEW都回滚。

6.不同类中:REQUIRES 嵌套 REQUIRES_NEW,情况2:REQUIRES(1)发生异常,REQUIRES_NEW(2)无异常,1的事务回滚,2的事务正常提交。这种情况在4.5.3提及过。

7.不同类中:REQUIRES(1)嵌套 REQUIRES(2),(1) 中 try {(2)}catch{e.printStackTrace();} , 2异常 , 1与2都会回滚(尽管catch了),因为1,2在同一事务中,发生异常Rolling back,故都回滚(同一事务中,要么都提交,要么都不提交)

8.不同类中:REQUIRES(1)嵌套 REQUIRES_NEW(2),(1) 中 try {(2)}catch{e.printStackTrace();} , 2异常, 1不回滚,2回滚,因为2在新事务中,发生异常Rolling back,且异常被1catch不被1感知,故1不回滚,2回滚。


http://chatgpt.dhexx.cn/article/FeRWZHZ3.shtml

相关文章

Spring事务、事务隔离级别、事务传播机制

Spring事务、事务隔离级别、事务传播机制 一、为什么需要事务?(回顾)二、Spring中事务的实现2.1 MySQL中的事务使用 (回顾)2.2 Spring编程式事务2.3 Spring 声明式事务2.3.1 Transactional 使用2.3.2 Transactional 作用范围2.3.3 Transactional 参数说明2.3.4 注意…

Spring 事务和事务的传播机制

1.Spring 中事务的实现方式 Spring 中的操作主要分为两类: 编程式事务 (了解) 声明式事务 编程式事务就是手写代码操作事务, 而声明式事务是利用注解来自动开启和提交事务. 并且编程式事务用几乎不怎么用. 这就好比汽车的手动挡和自动挡, 如果有足够的的钱, 大部分人应该都会选…

【Spring Boot】事务和事务传播机制

文章目录 1. 事务简单介绍2. Spring 中事务的实现2.1 Spring 手动操作事务2.2 Spring 声明式事务 3. Transactional 注解介绍3.1 Transactional 作用范围3.2 Transactional 参数说明3.3 Transactional 出现异常注意事项3.4 Transactional 工作原理 4. 事务隔离级别4.1 事务特性…

SpringBoot事务传播机制

Spring的事务传播机制:是指规定当程序中出现了多个方法出现了嵌套调用的时候,事务是如何进行传递的 支持当前事务:要有房子的 不支持当前事务:不许要有房子的 嵌套事务 1)定义:咱们之前所说的事务,都是针对一个方法的,咱们的Spring事务传播机…

Spring的事务传播机制(通俗易懂)

概述 Spring的事务传播机制有7种,在枚举Propagation中有定义。 1.REQUIRED PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,该设置是最常用的默认设置。 Tra…

Spring中的事务传播机制

目录 前言 1、Spring(Spring Boot)实现事务 1.1、通过代码的方式手动实现事务 1.2、通过注解Transactional的方式实现声明式事务 1.2.1、实现: 1.2.2、程序中有try-catch时,程序发生异常事务不会回滚 解决方案一:将异常抛出去 …

事务的7种传播机制和演示

文章目录 一、事务的传播机制1.1、nested 事务的几点说明: 二、示例2.1、前言:2.2、准备测试方法1)创建beans.xml,开启事务2)创建实体类和表(表创建读者可自定义创建)3)创建service接…

事务传播行为

原文作者:https://blog.csdn.net/soonfly/article/details/70305683 事务传播行为 什么叫事务传播行为?听起来挺高端的,其实很简单。 即然是传播,那么至少有两个东西,才可以发生传播。单体不存在传播这个行为。 事务传…

[事务] 事务的传播机制

前言: Spring的事务,也就是数据库的事务操作,符合ACID标准,也具有标准的事务隔离级别。 但是Spring事务有自己的特点,也就是事务传播机制。 所谓事务传播机制,也就是在事务在多个方法的调用中是如何传递的&…

事物的传播机制

目录 1、事务的传播机制 2、测试 2.1、准备测试方法 2.2、事务传播机制的测试 2.2.1、REQUIRED 2.2.2、NOT_SUPPORTED 2.2.3、REQUIRES_NEW 2.2.4、MANDATORY 2.2.5、NEVER 2.2.6、SUPPORTS 2.2.7、NESTED 事务传播机制:就是事务在多个方法的调用中是如何…

Spring事务传播机制

目录 一、事务在Spring中是如何运作的 1.1 开启事务(DataSourceTransactionManager.doBegin) 二、Spring的事务传播机制 2.1 子事务的传播机制为REQUIRED 2.2 子事务的传播机制为REQUIRES_NEW 2.3 子事务的传播机制为NESTED 当我们在使用Spring所提供的事务功能时&#x…

Spring事务传播的7种机制

Spring 事务传播机制包含以下 7 种: 1. Propagation.REQUIRED:默认的事务传播级别,它表示如果当前存在事务,则加入该事务;如果 当前没有事务,则创建一个新的事务。 2. Propagation.SUPPORTS:如果…

事务的传播机制

目录 1.形象说明: 2.代码演示: 2.1 REQUIRED 2.1.1 验证共用一个事务 2.1.2 验证当前没有事务,就新建一个事务 2.2 SUPPORTS 2.2.1 支持使用当前事务 2.2.2 如果当前事务不存在,则不使用事务 2.3 MANDATORY 2.3.1 支持…

Spring事务传播机制详解

前言: Spring的事务,也就是数据库的事务操作,符合ACID标准,也具有标准的事务隔离级别。 但是Spring事务有自己的特点,也就是事务传播机制。 所谓事务传播机制,也就是在事务在多个方法的调用中是如何传递的&…

反射原理详谈

什么是反射? 反射是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为 Java 语言…

Java反射的作用与原理

Java反射的作用与原理 定义 反射机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。在Java中,只要给定类…

彻底搞懂java反射技术及其原理

概述:反射是java中最强大的技术之一,很多高级框架都用到了反射技术,面试中也是经常问的点,所以搞懂反射非常重要! 文章目录 1.反射是什么?2.反射的底层原理3.三种方式获取Class对象4.反射的优缺点5.反射的应用场景6.反射的常用API 1.反射是什么? java反射机制指…

java反射原理-重要

一,反射是什么(反射是框架设计的灵魂) 1,JAVA反射机制是在运行状态中 对于任意一个类,都能够知道这个类的所有属性和方法; 对于任意一个对象,都能够调用它的任意一个方法和属性; …

java 反射机制原理 简述

什么是反射机制? 1、在运行状态中,对于任意一个类,都能够知道这个类的属性和方法。 2、对于任意一个对象,都能够调用它的任何方法和属性。这种动态获取信息以及动态调用对象的方法的功能称为JAVA的反射。 反射的作用 1、在运行…

java反射如何实现的_Java反射实现原理

Java反射应用十分广泛,例如spring的核心功能控制反转IOC就是通过反射来实现的,本文主要研究一下发射方法调用的实现方式和反射对性能的影响。 如下为Method类中invoke方法,可以看出该方法实际是将反射方法的调用委派给MethodAccessor&#xf…