Spring事务及事务传播机制(2)

@Transactional详解

我们主要学习@Transactional注解当中的三个常见属性:

1.rollbackFor: 异常回滚特性. 指定能够触发事务回滚的异常类型. 可以指定多个异常类型.

2.Isolation:事务的隔离级别. 默认值为Isolation.DEFAULT

3.propagation: 事务的传播机制. 默认为Propagation.REQUIRED.

rollbackFor

@Transactional 默认只在遇到运行时异常和Error才会进行回滚, 非运行时异常不回滚. 即Exception的子类中, 除了RuntimeException及其子类.

之前我们通过制造一个运行时异常, 发现事务回滚了, 接下来把异常改为如下代码:

    @Transactional
    @RequestMapping("/registry")
    public String registry(String name, String password) throws IOException {
        //用户注册
        userService.registryUser(name, password);
        log.info("用户数据插入成功");
        if(true) {
            throw new IOException();
        }
        return "注册成功";
    }

运行程序:

发现虽然程序抛出了异常, 但是事务仍被提交:

如果需要所有的异常都回滚, 需要配置@Transactional注解当中的rollbackFor属性, 通过rollbackFor这个属性指定出现何种异常类型时事务进行回滚.

@Transactional(rollbackFor = Exception.class)

运行代码, 观察现象:

发现这时事务进行了回滚.

结论:

在Spring事务管理中, 默认只在遇到运行时异常RuntimeException和Error时才会进行回滚.

如果需要回滚指定类型的异常, 可以通过rollbackFor属性来指定

事务隔离级别

回顾: 并发读数据库可能引发的问题

1.脏读: 指一个事务A读取到了事务B还没有提交的数据, 在之后事务B进行了修改, 这时候事务A读到的数据称为脏数据, 也叫脏读. (解决方案: 给写操作加锁, 即一个事务在没有提交之前, 不能被读取).

2.不可重复读: 一个事务先后两次读取到的数据不一致, 可能是两次读取过程中插入了一个新的事务更新了原有的数据, 注:侧重于修改(解决方案: 给读操作加锁, 即一个事务在没有读完的时候不会插入其它的数据).

3.幻读: 同一个事务中, 多次查询的结果集返回不一致. 比如事务A查询了几列数据, 而事务B在此时又插入了新的几列数据(注:侧重于新增或删除),先前的事务在接下来的查询中, 就会发现几列是它先前所没有的, 这就是幻读. (解决方案: 进一步提高事务之间的隔离性, 即串行化).

MySQL数据库事务隔离级别

1.读未提交: 最低的隔离级别, 在该级别内可以看到其它事务未提交的数据.

因为其它未提交的数据可能会发生回滚, 但是在该级别下仍然是可以读到的, 这个读到的就是脏数据.

2.读已提交: 在该级别内, 一个事务只能读取其它事务中已提交的数据(相当于加写锁).

 在该隔离级别内不会存在脏读的问题. 但由于在事务的执行中可以读取到其它事务提交的结果,  所以在不同时间读取到的数据可能不一致.

3.可重复读: 事务不会读到其它事务对已有数据的修改, 即使其它事务已经提交. 也就可以确保同一事务多次查询到的结果一致, 但是对于其它事务新插入的数据, 是可以感知到的. 这就引发了幻读问题. 可重复读, 是MySQL中默认的事务隔离级别(相当于加读锁和写锁).

比如此级别的事务正在执行时, 另一个事务中新增了一条数据, 但是由于每次读取的时候结果都一样, 所以导致查询不到这条数据. 

 4.串行化: 是事务的最高隔离级别, 它会强制事务排序, 使之不会发生冲突. 但是因为资源消耗很大, 所以不太常用.

Spring中的事务隔离级别:

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

2.Isolation.READ_UNCOMMITTED:读未提交

3.Isolation.READ_COMMITED: 读已提交.

4.Isolation.REPEATABLE_READ: 可重复读

5.Isolation.SERIALIZABLE: 串行化.

spring中的事务隔离级别也可以通过类似之前的rollbackFor的方式设置:

@Transactional(isolation = Isolation.READ_COMMITTED)

Spring事务传播机制

什么是事务传播机制

事务传播机制就是: 多个事务方法存在调用关系时, 事务是如何在这些方法间进行传播的.

比如有两个方法A, B都被@Transactional修饰, A方法调用B方法, 此时B方法运行时, 是加入A的事务, 还是创建一个新的事务呢?

这就涉及到了事务的传播机制.

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

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

事务的传播机制有哪些?

@Transactional注解支持事务传播机制的设置, 通过propagation属性来指定传播行为.

 Spring事务传播机制有以下7种(以下结合一对新人要结婚的例子来说明):

1.Propagation.REQUIRED: 默认的事务隔离级别. 如果当前存在事务, 则加入该事务. 如果当前没有事务, 则创建一个新的事务.(需要有房子, 如果你有房, 我们就一起住, 如果你没房, 我们就一起买房).

2.Propagation.SUPPORTS: 如果当前存在事务, 则加入该事务. 如果当前没有事务, 则继续以非事务的方式继续执行.(可以有房子, 如果你有房, 那就一起住, 如果没房, 那就租房).

3.Propagation.MANDATORY: 如果当前存在事务, 则加入该事务. 如果当前没有事务, 则抛出异常.(必须有房子, 要求必须有房, 如果没房就不结婚).

4.Propagation.REQUIRES_NEW: 创建一个新的事务. 如果当前存在事务, 则把当前事务挂起.

(必须买新房, 不管你有没有房, 必须要两个人一起买房. 即使有房也不住)

5.Propagation.NOT_SUPPORTED: 以非事务的方式运行, 如果当前存在事务, 则把当前事务挂起. (不需要房, 不管你有没有房, 我都不住, 必须租房)

6,Propagation.NEVER: 以非事务的方式运行, 如果当前存在事务, 则抛出异常(不能有房子)

7.Propagation.NESTED: 如果当前存在事务, 则创建一个事务作为当前事务的嵌套事务运行, 如果没有事务, 则取值等价于Propagation.REQUIRED.(如果有房, 则以房子为根据地, 做点下生意.)

相关推荐

  1. Spring 事务事务传播机制

    2024-05-11 11:16:13       42 阅读
  2. 关于Spring @Transactional事务传播机制详解

    2024-05-11 11:16:13       46 阅读
  3. Spring 事务的种类 ? 传播机制 ?

    2024-05-11 11:16:13       38 阅读
  4. 简单讲讲spring事务传播机制

    2024-05-11 11:16:13       41 阅读
  5. Spring事务传播机制有哪些

    2024-05-11 11:16:13       38 阅读
  6. Spring Boot 事务传播机制详解

    2024-05-11 11:16:13       33 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-11 11:16:13       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-11 11:16:13       100 阅读
  3. 在Django里面运行非项目文件

    2024-05-11 11:16:13       82 阅读
  4. Python语言-面向对象

    2024-05-11 11:16:13       91 阅读

热门阅读

  1. 面试分享——Elasticsearch面试题

    2024-05-11 11:16:13       36 阅读
  2. Jenkins的原理及应用详解(一)

    2024-05-11 11:16:13       31 阅读
  3. Spring线程池配置

    2024-05-11 11:16:13       31 阅读
  4. NLP经典入门论文

    2024-05-11 11:16:13       31 阅读
  5. 蓝桥杯备战4.双子数

    2024-05-11 11:16:13       27 阅读
  6. 程序员必须学会的道理,少走十年弯路!

    2024-05-11 11:16:13       29 阅读
  7. c#文心接口应用举例

    2024-05-11 11:16:13       36 阅读
  8. 从零开始学习MySQL 事务处理

    2024-05-11 11:16:13       26 阅读