SpringBoot事务配置管理(5大隔离级别及传播机制详解)

SpringBoot事务配置管理(5大隔离级别及传播机制详解)-mikechen

什么是事务?

事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消。

用专业的话来说,事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消。也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做。

 

事务的特性?

事务有四个特性(ACID):

1.原子性(Atomicity)

事务是数据库的逻辑工作单位,事务中包括的诸操作要么全做,要么全不做。

2.一致性(Consistency)

事务必须使数据库从一个一致性状态变成另外一个一致性状态,事务开始和完成,数据必须保持一致。(数据不被破坏)

3.隔离性(Isolation)

一个事务的执行不能被其他事务干扰。

比如:当多个事务处于并发访问同一个数据库资源时,事务之间相互影响程度,不同的隔离级别决定了各个事务对数据资源访问的不同行为。

4.持续性/永久性(Durability)

一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。

 

SpringBoot事务配置?

1.依赖导入

在SpringBoot中使用事务,需要导入mybatis依赖:

<dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.0</version>
        </dependency>

导入依赖之后,SpringBoot会自动注入DataSourceTransactionManager ,无需其他配置就可使用@Transactional注解进行事务的使用。

2.具体示例

@Service
public class UserServiceImpl implements UserService {
    @Resource
    private UserMapper userMapper;
    
    @Override
    @Transactional
    public void isertUser2(User user) throws Exception {
        // 插入用户信息
        userMapper.insertUser(user);
        // 手动抛出异常
        throw new SQLException("数据库异常");
    }
}

 

SpringBoot事务隔离级别?

事务隔离级别解决的是多个事务同时调⽤⼀个数据库的问题,如下图所示:

SpringBoot事务配置管理(5大隔离级别及传播机制详解)-mikechen

我们可以看 org.springframework.transaction.annotation.Isolation 枚举类中定义了五个表示隔离级别的值:

public enum Isolation {  
    DEFAULT(-1),
    READ_UNCOMMITTED(1),
    READ_COMMITTED(2),
    REPEATABLE_READ(4),
    SERIALIZABLE(8);
}

1.DEFAULT :默认值

Default是SpringBoot的隔离级别默认值,表示使用底层数据库的默认隔离级别。

大部分数据库为READ_COMMITTED,MySql默认隔离级别为REPEATABLE_READ。

2.Read uncommitted(读未提交)

一个事务可以读取另一个事务修改但还没有提交的数据。

3.Read committed(读提交)

一个事务只能读取另一个事务已经提交的数据。

比如:如果是一个读事务线程,则允许其他事务读写,如果是写事务将会禁止其他事务访问该行数据,该隔离级别避免了脏读,但是可能出现不可重复读。

事务A事先读取了数据,事务B紧接着更新了数据,并提交了事务,而事务A再次读取该数据时,数据已经发生了改变。

4.Repeatable read(可重复读取)

一个事务在整个过程中可以多次重复执行某个查询,并且每次返回的记录都相同。即使在多次查询之间有新增的数据满足该查询,这些新增的记录也会被忽略。

5.Serializable(可序化)

提供严格的事务隔离,它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行。

指定方法可以通过使用 isolation 属性设置,例如:

@Transactional(isolation = Isolation.DEFAULT)

 

SpringBoot事务传播行为?

事务传播机制解决的是⼀个事务在多个节点:⽅法中传递的问题,如下图所示:

SpringBoot事务配置管理(5大隔离级别及传播机制详解)-mikechen

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

我们可以看 org.springframework.transaction.annotation.Propagation 枚举类中定义了6个表示传播行为的枚举值:

public enum Propagation {  
    REQUIRED(0),
    SUPPORTS(1),
    MANDATORY(2),
    REQUIRES_NEW(3),
    NOT_SUPPORTED(4),
    NEVER(5),
    NESTED(6);
}

1.REQUIRED

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

2.SUPPORTS

如果当前存在事务,则加⼊该事务,如果当前没有事务,则以⾮事务的⽅式继续运⾏。

3.MANDATORY

如果当前存在事务,则加入该事务,如果当前没有事务,则抛出异常。

4.REQUIRES_NEW

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

5.NOT_SUPPORTED

以⾮事务⽅式运⾏,如果当前存在事务,则把当前事务挂起。

6.Propagation.NESTED

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

 

陈睿mikechen

10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。

关注「mikechen」公众号,获取更多技术干货!

后台回复面试即可获取《史上最全阿里Java面试题总结》,后台回复架构,即可获取《阿里架构师进阶专题全部合集

评论交流
    说说你的看法