本文主要是介绍MySQL事务--八股文(小林coding个人提炼版本),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1.事务的特性有哪些
原子性、隔离性、一致性、持久性
2.并发事务会引发什么问题,他们的概念是什么
脏读、不可重复读、幻读。
脏读:读到了其他事务还未提交的数据
不可重复读:在一个事务上,查询的数据不一致。
幻读:在一个事务上,查找的数据的数量不一样
3.事务的隔离级别有哪些以及他们的概念,还有他们发生的现象?
读未提交:他的操作对所有事务可见
读已提交:只有提交后,其数据才对其他事务可见。解决了脏读
可重复读:一个事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的。解决了不可重复读(Innodb默认的)
串行化:会对记录加上读写锁,在多个事务对这条记录进行读写操作时,如果发生了读写冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。解决了幻读
4.可重复读解决幻读
首先为什么不推荐直接变成串行化,因为这样子会导致并发的时候,性能很多。
方法:
- 针对快照读(普通 select 语句),是通过 MVCC 方式解决了幻读,因为可重复读隔离级别下,事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的,即使中途有其他事务插入了一条数据,是查询不出来这条数据的,所以就很好了避免幻读问题。
- 针对当前读(select ... for update 等语句),是通过 next-key lock(记录锁+间隙锁)方式解决了幻读,因为当执行 select ... for update 语句的时候,会加上 next-key lock,如果有其他事务在 next-key lock 锁范围内插入了一条记录,那么这个插入语句就会被阻塞,无法成功插入,所以就很好了避免幻读问题。
5.「读提交」和「可重复读」隔离级别的事务来说,它们是通过 Read View 来实现的,它们的区别在于哪里?
读提交:每次语句操作的时候,都会生成快照
可重复读:每次事务的时候会生成快照
两个隔离级别实现是通过「事务的 Read View 里的字段」和「记录中的两个隐藏列」的比对,来控制并发事务访问同一个记录时的行为,这就叫 MVCC(多版本并发控制)
在可重复读隔离级别中,普通的 select 语句就是基于 MVCC 实现的快照读,也就是不会加锁的。而 select .. for update 语句就不是快照读了,而是当前读了,也就是每次读都是拿到最新版本的数据,但是它会对读到的记录加上 next-key lock 锁。
6.不可重复读出现脏读的场景
1.可重复读隔离级别下,事务 A 第一次执行普通的 select 语句时生成了一个 ReadView,之后事务 B 向表中新插入了一条 id = 5 的记录并提交。接着,事务 A 对 id = 5 这条记录进行了更新操作,在这个时刻,这条新记录的 trx_id 隐藏列的值就变成了事务 A 的事务 id,之后事务 A 再使用普通 select 语句去查询这条记录时就可以看到这条记录了,于是就发生了幻读。
2.还有一种
- T1 时刻:事务 A 先执行「快照读语句」:select * from t_test where id > 100 得到了 3 条记录。
- T2 时刻:事务 B 往插入一个 id= 200 的记录并提交;
- T3 时刻:事务 A 再执行「当前读语句」 select * from t_test where id > 100 for update 就会得到 4 条记录,此时也发生了幻读现象。
这篇关于MySQL事务--八股文(小林coding个人提炼版本)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!