Spring事物和事务的传播机制

事务的定义:将一组操作封装到一个执行单元,要么全部成功,要么全部失败。

一、Spring中事务的实现

Spring中事务的操作分为两类:
1.编程式事务(手动写代码操作事务)
2.声明式事务(利用注解自动开启和提交事务)

1.1 Spring编程式事务

实现步骤:
a.开启事务
b.提交事务 / 回滚事务
在这里插入图片描述

package com.example.demo.controller;

import com.example.demo.model.UserInfo;
import com.example.demo.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {

    @Autowired
    private UserService userService;

    //事务管理器
    @Autowired
    private DataSourceTransactionManager transactionManager;
    //事务属性对象
    private TransactionDefinition transactionDefinition;

    @RequestMapping("/add")
    public int add(UserInfo userInfo){
        //获取事务(开启事务)
        TransactionStatus transactionStatus = transactionManager.getTransaction(transactionDefinition);
        int result = userService.add(userInfo);
        log.info("添加结果:"+result);
        transactionManager.commit(transactionStatus);//提交事务
//        transactionManager.rollback(transactionStatus);//回滚事务
        return result;
    }
}

1.2 Spring声明式事务

添加注解@Transactional
无需手动开启事务和提交事务,进⼊方法时自动开启事务,方法执行完会自动提交事务,如果中途发生了没有处理的异常会自动回滚事务。
在这里插入图片描述
当中途发生了没有处理的异常,则数据不会进入数据库,而是会回滚。
在这里插入图片描述
在这里插入图片描述

1.2.1@Transactional 作用范围

1.Transactional既可以修饰类也可以修饰方法。
当修饰类时:表明该注解对当前类中所有被public修饰的方法都会生效(即会自动的开启和提交事务)
2.当修饰方法时:此注解只能用在public方法上,否则将会不生效。

1.2.2 @Transactional参数说明

在这里插入图片描述

1.2.3@Transactional注意事项

@Transactional在异常被捕获的情况下,不会进行事务的自动回滚。
在这里插入图片描述
解决方案:
1.可以将异常重新抛出
在这里插入图片描述
2.手动回滚事务
在这里插入图片描述

1.3@Transactional工作原理

@Transactional 是基于 AOP 实现的,AOP 又是使用动态代理实现的。@Transactional 在开始执行业务之前,通过代理先开启事务,在执行成功之后再提交事务。如果中途遇到异常,则回滚事务。

二、 事务隔离级别

2.1事务特性回顾

事务有四大特性(ACID),原子性、持久性、一致性、隔离性
1.原子性:一个事务中的所有操作,要么全部完成、要么全部不完成,不会在中间某个环节结束。事务在执行过程中发生错误,会被回滚到事务开始前的状态,就像这个事务从来没有被执行过一样。
2.一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。例如:转账的业务中,无论事务是否成功,转账者和收款人的总额应该不变。
3.隔离性:数据库允许多个并发事务同时对其数据进行读写和修改,并发访问数据库时,一个用户的事务不应该被其他事务所影响,各并发事务之间数据库是独立的。事务隔离有多个级别:读未提交、读已提交、可重复读、串行化。
4.持久性:一个事务被提交后,它对数据库中数据的改变是持久的。即便数据库发生故障也不应该对其有影响。
以上四种特性中只有隔离性是可以设置的,设置事务的隔离级别是用来保障多个并发事务执行更可控,更符合操作者的预期。

2.2Spring中事务的隔离级别

2.2.1Mysql事务隔离级别

有四种:
1.READ UNCOMMITTED:读未提交,该隔离级别的事务可以看到其他的事务没有提交的数据。该隔离级别因为可以读取到其他事务中未提交的数据,而未提交的数据可能会发生回滚,因此我们把该级别读取到的数据称之为脏数据,把这个问题称之为脏读。
2.READ COMMITTED:读已提交,该隔离级别的事务能够读取到已提交事务的数据,因此它不会有脏读问题。但由于在事务的执行中可以读取到其他事务提交的结果,所以在不同时间
的相同 SQL 查询中,可能会得到不同的结果,这种现象叫做不可重复读。
3.REPEATABLE READ:可重复读,是Mysql默认的事务隔离级别,它能够确保同一事物多次查询的结果一致。但也会出现幻读的问题。
4.SERIALIZABLE:序列化,事务最高隔离级别,它会强制事务排序,使之不会发生冲突,从而解决了脏读、不可重复读和幻读问题,但因为执行效率低,所以真正使用的场景并不多。
在这里插入图片描述

脏读、不可重复读、幻读的具体解释:
1.脏读:当一个事务正在访问数据并对其进行了修改,但是还没提交事务,这时另外一个事务也访问了这个数据,然后使用了这个数据,因为这个数据的修改还没有提交到数据库,所以另外一个事务读取的数据就是“脏数据”,这种行为就是脏读。
2.不可重复读:指在一个事务内多次读取同一数据,在这个事务还没结束时,另一个事务也访问了这个数据并对这个数据进行了修改,那么就可能造成第一个事务两次读取的数据不一致,这种问题就叫不可重复读。
3.幻读:幻读与不可重复读类似,指一个事务读取了几行数据,这个事务还没结束,接着另外一个事务插入了一些数据,在随后的查询中,第一个事务读取到的数据就会比原本读取到的多,就好像发生了幻觉一样,所以称为幻读。

不可重复读与幻读的区别:
不可重复读的重点是修改,幻读的重点是新增或者是删除。

2.2.1Spring中事务的隔离级别

隔离级别的设置:
在这里插入图片描述
五种隔离级别:
在这里插入图片描述
1.Isolation.DEFAULT:以连接的数据库的事务隔离级别为主。
2. Isolation.READ_UNCOMMITTED:读未提交
3. Isolation.READ_COMMITTED:读已提交
4. Isolation.REPEATABLE_READ:可重复读
5. Isolation.SERIALIZABLE:串行化

三、Spring 事务传播机制

Spring 事务传播机制定义了多个包含了事务的方法,相互调⽤时,事务是如何在这些方法间进行传递的。
事务隔离级别是保证多个并发事务执行的可控性的(稳定性的),而事务传播机制是保证⼀个事务在多个调用方法间的可控性的(稳定性的)。

3.1事务的传播机制

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

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

3.Propagation.MANDATORY:
如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。

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

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

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

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

传播机制分类:
在这里插入图片描述

3.2事务传播机制的设置

在这里插入图片描述
在这里插入图片描述

3.3嵌套事务

嵌套事务NESTED与加入事务 REQUIRED 的区别:
REQUIRED 如果回滚就是回滚所有事务,不能实现部分事务的回滚。但是嵌套事务不会回滚嵌套之前的事务,也就是说嵌套事务可以实现部分事务回滚。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值