一、什么是事务?
- 事务就是用户定义的一系列执行SQL语句的操作, 这些操作要么完全地执行,要么完全地都不执行, 它是一个不可分割的工作执行单元。
- 事务的使用场景:
在日常生活中,有时我们需要进行银行转账,这个银行转账操作背后就是需要执行多个SQL语句,假
如这些SQL执行到一半突然停电了,那么就会导致这个功能只完成了一半,这种情况是不允许出现,
要想解决这个问题就需要通过事务来完成。
二、事务的四大特性
原子性
事务要么成功要么失败,如果失败了就会进行回滚,由undolog日志保证。
隔离性
事务与事务之间是互不干扰,由MVCC机制保证。
持久性
当事务提交之后,数据的修改要被持久化保存下来,当数据库重启后,数据的值需要是被修改后的值,由redolog日志保证。
一致性
数据库中的数据在事务执行前后是一致的,由原子性、隔离性、持久性保证。
三、四大隔离级别
有哪些隔离级别,这些隔离级别分别解决了什么问题?
- 读未提交:不能解决任何问题,没有提交事务的数据也读到了;
- 读已提交:解决了脏读问题;
- 可重复读:解决了脏读、不可重复读和快照下的幻读问题
- 串行化:解决了脏读、不可重复读、幻读的问题,但是效率比较低。
什么是脏读、不可重复读、幻读?
脏读:读取到其他事务未提交的数据。
不可重复读:一次事务多次读取同一行数据,结果不一样。这里着重的是同一行数据的修改。
幻读:在同一个事务里查询的两次数据量不一样。
四、MVCC机制
图示
什么是快照读,什么是当前读,readview是什么?
快照读:
事务读取数据时,会读取一个时间点(事务开始时)的数据快照,这个快照保持了事务开始时数据库中的数据的状态。在事务执行期间,其他事务对数据的修改不会影响到当前事务的读取结果。
当前读:
事务读取的是最新的数据,而不是快照。如果在事务开始后,有其他事务修改了数据,当前读会读取最新的数据,并且对读取的数据加锁,以防止其他事务修改。
readview:
ReadView 其实就是一个保存事务ID的list列表。记录的是本事务执行时,MySQL还有哪些事务在执行,且还没有提交。(当前系统中还有哪些活跃的读写事务)
它主要包含这样几部分:
- m_ids,当前有哪些事务正在执行,且还没有提交,这些事务的 id 就会存在这里;
- min_trx_id,是指 m_ids 里最小的值;
- max_trx_id,是指下一个要生成的事务 id。下一个要生成的事务 id 肯定比现在所有事务的 id 都大;
- creator_trx_id,每开启一个事务都会生成一个 ReadView,而 creator_trx_id 就是这个开启的事务的 id。
rr和rc的隔离级别下,readview的生成时机?
可重复读隔离级别下(rr):第一次执行select时生成readview,后续都会使用该readview
读已提交隔离级别下(rc):每次select都会生成新的readview
undolog版本链怎么生成的?
在事务开始时,MySQL 会为该事务分配一个唯一的事务ID,对事务进行修改时,会将操作写入undo log日志,并且每一次操作会通过指针rollPoint进行链接。
readview具体和undolog怎么比较的?–四个判断依据
首先readview有四个隐藏参数:min_trx(最小事务id)、max_trx+1(最大事务id+1)、创建者/当前事务id、当前活跃事务列表。
● 如果事务ID小于min_trx,表示该事务对当前事务是可见的,可以读取;
● 如果当前事务ID等于创建者事务ID,可以读取;
● 如果事务ID大于max_trx+1,表示事务对当前事务是不可见的,不可以读取;
● 如果事务ID在min_trx和max_trx之间,并且不在当前活跃事务列表中,表示事务对当前事务是可见的,可以读取;如果在当前活跃事务列表中,表示该事务是未提交的,对于当前事务是不可见的,不可以读取。
MVCC能完全解决幻读问题吗?
不能,它只是解决快照读语义(select)下的幻读,如果要解决当前读(insert、update、delete、select for update)的幻读问题,需要通过临键锁(间隙锁+记录锁解决),也就是使用 select for update
五、隔离级别为什么使用RR级别?
如果使用RC隔离级别下,就会出现主库和从库的数据不一致的问题。