spring 事务
ACID介绍
A 原子性: 要么都成功,要么都失败!
C 一致性:状态一直,结果完整。
I 隔离性: 别人修改后能不能被看到
D 持久性: 事务提交之后才会保存到数据库
MySQL数据库默认是 可重复读
可重复读(REPEATABLE READ) 也就是一个事务中 多次读取同一条数据结果是一样的,其它事务修改不受影响。
读未提交(READ UNCOMMITTED) 其它线程修改了数据 当前线程能获取到 如果其它线程回滚了 就照成了脏读。
读已提交(READ COMMITTED) 别人提交了才能读取到。
串行化(SERIALIZABLE)查询也会加锁。排队执行。
脏读:可以读取未提交的数据。RC 要求解决脏读;
不可重复读:同一个事务中多次执行同一个select, 读取到的数据发生了改变(被其它事务update并且提交);
可重复读:同一个事务中多次执行同一个select, 读取到的数据没有发生改变(一般使用MVCC实现);RR各级级别要求达到可重复读的标准;
幻读:同一个事务中多次执行同一个select, 读取到的数据行发生改变。也就是行数减少或者增加了(被其它事务delete/insert并且提交)。SERIALIZABLE要求解决幻读问题;
https://www.hollischuang.com/archives/6854
结论
在RC级别中,幻读是没有办法解决的,因为RC中快照读是每一次都会重新生成快照,并且RC中也不会有间隙锁。
在RR级别中,因为有MVCC机制,对于普通的无锁查询,这种是属于快照读的,RR的快照读在同一个事务中只会读一次,所以在事务过程中,其他事务的变更不会影响到当前事务的查询结果。所以这种幻读是可以解决的。
当时,MVCC只能对快照读起作用,而对于加锁的读请求,这种属于当前读,当前读的话是可以查询到其他事务的变更的,所以会产生幻读。
想要解决幻读,可以使用Serializable这种隔离级别,或者使用RR也能解决大部分的幻读问题。
在RR级别下,为了避免幻读的发生,要么就是使用快照读,要么就是在事务一开始就加锁。

浙公网安备 33010602011771号