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