Spring 事务 (编程式 & 声明式, Spring 事务传播机制)

简介: Spring 事务 (编程式 & 声明式, Spring 事务传播机制)

事务

事务是一组操作的集合, 是一个不可分割的整体

事务会把所有的操作作为一个整体, 一起向数据库提交或是撤销操作请求. 所以这组操作要么同时成功, 要么同时失败

Spring 中事务的实现

  1. 编程式 (手动写代码操作事务)
  2. 声明式 (通过注解自动开启和提交事务)

编程式事务

  1. 开启事务 / 获取事务, 通过两个 Spring 内置对象获取
  • DataSourceTransactionManager 事务管理器, 用来获取, 提交或回滚事务
  • TransactionDefinition 定义事务的属性, 事务隔离级别, 事务传播机制, 回滚规则 …
  1. 提交事务
  2. 回滚事务

Spring 通过 DataSourceTransactionManager (事务管理器) 和 TransactionDefinition (事务的属性) 来获取事务

@Controller
public class BasicController {
  // 获取事务管理器
    @Autowired
    private DataSourceTransactionManager dataSourceTransactionManager;
    
  // 定义事务的属性
    @Autowired
    private TransactionDefinition transactionDefinition;

    @RequestMapping("/registry")
    public String registry() {
        // 获取事务 / 开启事务 (transactionStatus 为事务的一个状态, 可以理解为数据库的一个快照)
        TransactionStatus transactionStatus =
                dataSourceTransactionManager.getTransaction(transactionDefinition);

        // 业务逻辑
        User user = new User();
        user.setAge(18);
        user.setName("zrj");
    
    //提交事务
        dataSourceTransactionManager.commit(transactionStatus); 
        
        //回滚事务
//        dataSourceTransactionManager.rollback(transactionStatus); 
        return "ok";
    }
}

声明式事务

使用注解 @Transactional

既是类注解, 也是方法注解

会对注解范围内所有的 public 修饰的方法 生效

@Transactional :

如果方法执行过程中, 出现异常, 且未被捕获, 就进行事务回滚.

如果异常被程序捕获, 则方法对异常无感知, 认为本次执行成功, 就会进行事务提交. 若异常被捕获仍想回滚:

  • 将捕获的异常再次抛出
  • 手动回滚事务 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
@RestController
public class PathVariableController {
    @Transactional()
    @RequestMapping("/registry")
    public String registry() {
        User user = new User();
        user.setAge(18);
        user.setName("zrj");
        return "ok";
    }
}

@Transactional 注解的常用属性

  1. rollbackFor : 异常回滚属性. 执行能够触发事务回滚的异常类型, 默认只有 运行时异常和 error 才会触发事务回滚, 其他类型异常并不会触发回滚操作
  1. Isolation : 事务的隔离级别. 默认为 Isolation.DEFAULT
  2. propergation : 事务的传播机制, 默认值为 Propergation.REQUIRED

事务的隔离级别解决 多个事务同时调用一个数据库的问题

事务的传播机制解决 一个事务在多个节点(方法)中传播的问题

Spring 事务的传播机制 – 7种

Propergation.REQUIRED : 如果当前存在事务, 则加入该事务, 如果当前不存在事务, 则创建一个事务

Propergation.SUPPORTS : 如果当前存在事务, 就加入该事务, 如果当前不存在事务,就以非事务的方式继续执行

Propergation.MANDATORY : 强制性, 如果当前存在事务, 就加入该事务, 如果当前不存在事务, 就报错

Propergation.REQUIED_NEW : 创建一个新事务, 如果当前存在事务, 就将当前事务挂起

Propergation.NOT_SUPPORTED :非事务的方式运行, 如果当前存在事务, 就将当前事务挂起

Propergation.NEVER : 以非事务的方式运行, 如果当前存在事务, 就抛出异常

Propergation.NESTED : 如果当前存在事务, 则创建一个事务作为当前事务的嵌套事务/子事务来运行, 如果没有事务, 则创建一个事务


NESTED & REQUIRED

  • 如果事务全部执行成功, 二者的结果是一样的
  • 如果事务部分执行成功, 部分执行失败, REQUIRED 加入事务 会导致整个事务 全部回滚, NESTED 嵌套事务 可以实现 部分回滚 (savepoint 机制)

目录
相关文章
|
25天前
|
前端开发 Java 数据库
浅谈Spring AOP 面向切面编程 最通俗易懂的画图理解AOP、AOP通知执行顺序~
浅谈Spring AOP 面向切面编程 最通俗易懂的画图理解AOP、AOP通知执行顺序~
|
25天前
|
XML Java 数据格式
技术好文:Spring基础篇——AOP切面编程
技术好文:Spring基础篇——AOP切面编程
|
10天前
|
Java 数据库连接 API
Spring事务管理嵌套事务详解 : 同一个类中,一个方法调用另外一个有事务的方法
Spring事务管理嵌套事务详解 : 同一个类中,一个方法调用另外一个有事务的方法
|
10天前
|
Java Spring
spring 事务控制 设置手动回滚 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
spring 事务控制 设置手动回滚 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
|
10天前
|
XML Java 关系型数据库
面试一口气说出Spring的声明式事务@Transactional注解的6种失效场景
面试一口气说出Spring的声明式事务@Transactional注解的6种失效场景
|
1月前
|
XML Java 数据库
Spring框架第五章(声明式事务)
Spring框架第五章(声明式事务)
|
15天前
|
Java Spring
解析Spring Boot中的事务管理机制
解析Spring Boot中的事务管理机制
|
21天前
|
XML Java 关系型数据库
Spring6(四):JUnit、事务(2)
Spring6(四):JUnit、事务(2)
14 0
|
21天前
|
Java 测试技术 数据库
Spring6(四):JUnit、事务(1)
Spring6(四):JUnit、事务(1)
14 0
|
21天前
|
Java 测试技术 数据安全/隐私保护
Spring Boot中的AOP编程实践
Spring Boot中的AOP编程实践