Spring 事务管理 4种隔离级别

数据库事务的隔离级别有如下几种
public enum Isolation {
    DEFAULT(-1),
    READ_UNCOMMITTED(1),
    READ_COMMITTED(2),
    REPEATABLE_READ(4),
    SERIALIZABLE(8);

    private final int value;

    private Isolation(int value) {
        this.value = value;
    }

    public int value() {
        return this.value;
    }
}

下面分别进行解释:

Default  即默认级别 其中 Sql Server ,Oracle 的默认级别为Read committed  mySql的默认隔离级别为 Repeatable read。

Read uncommitted 

读未提交:即一个事务可以读取另一个事务还没有提交的数据

这样可能导致读取脏数据:比如,A事务保存了 数据 data 但是还没有提交,这个时候 B事务就可以读取到data了,但是A事务出现了异常回滚,这个时候B已经获取了之前保存的脏数据。

Read committed

读提交:即一个事务只能读取另一个事务提交后的数据

这样会导致不可重复读:比如A开启事务,读取data为 A,此时 B开启事务,将data的数据修改为 B,这时在A事务里面 data仍旧为A,等候后续的操作时,就可能导致由于数据不是A而发生的异常。


Repeatable read

可重复读:就是在事务开启读取的时候,不在允许修改操作

比如A开启事务,读取data为A,此时B开始事务,修改data为B,此时事务B将失败,因为不允许修改(Update)操作

但是仍旧可能导致幻读问题(幻读问题是由于insert操作引起的)


幻读 比如读取某一个列数据的和,当事务A开启事务,读取列和为(100),就在这个时候事务B插入一条数据列(20),然后事务A打印列和(事务提交)结果打印的结果为120 ,而在事务中结果一直为 100 就好像是出现了幻觉一样,因而称为幻读。

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.NESTED)
    public int save() {
        personMapper.insert(Person.builder().name("A").age(12).build());
        // 此结果为 1
        System.out.println(personMapper.selectCount(null));
        try {
            //@Transactional(rollbackFor = Exception.class, propagation = Propagation.NESTED)
            b.save();
        } catch (Exception e) {

        }
        // 此结果为 2   在同一个事务中结果不一样
        return personMapper.selectCount(null);
    }

Serializable 在该级别下,事务串行化顺序执行,这样可以解决幻读的问题,但是效率低下,不推荐使用。

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页