mysql 原理 ~ 事务隔离机制

时间:2023-03-09 08:54:59
mysql 原理 ~ 事务隔离机制

简介: 事务隔离知多少
内容
  一 基础知识
  1 事务特性 ACID
  A 原子性 C 一致性 I 隔离性 D 持久性
  2 并行事务出现的问题
    1 脏读 读取了其他事务未提交的数据
     2 不可重复性读 1 在同一个事务内多次查询的结果不一致 2 可以通过for update or RR模式的MVCC避免这种现象 3 针对的是update/delete操作
     3 幻读 1 当前事务读第一次取到的数据比后来读取到数据条目少 通过 next  key lock避免

这里要注意

官方文档实际要表达的意义是“在同一个事务内,多次连续查询的结果是一样的,不会因其他事务的修改而导致不同的查询结果”

当前事务如果未发生更新操作(增删改),快照版本会保持不变,多次查询读取的副本是同一个;当前事务如果发生更新(增删改),再次查询时,会刷新快照版本

3 mysql隔离级别
   RU 读未提交 -> 其他事务可以读取未提交的事务
   RC 读已提交 -> 其他事务只能读取已提交的事务 可以避免(脏读) 不可避免(不可重复性读和幻读) 锁(record lock)
   RR 可重复性读-> 本事务在事务内多次读取的事务是一致的,不会产生变化,直到本事务提交 可以避免(脏读,不可复重复性读和幻读) 锁(record lock+gap lock)
   SE 串行化->事务之前是串行化执行的,包括select
 4 默认隔离级别
  mysql rr级别 oracle rc级别
  oracle应用迁移到mysql的时候要注意
  金融级别的建议使用RR
5 可重复性读和读已提交的区别

1 可重复性读是在事务开始的时候只创建一次视图函数 直到事务结束 效果等同于(start transaction with consistent snapshot) 查询事务开启前提交的数据

2 读已提交是在每次执行的时候都创建一次视图函数 直到事务结束 查询在事务内语句前提交的数据

6 RR模式下的更新问题
  问题描述 在RR模式下 select搜索的是旧库的快照,但是update更新的是新库的数据,导致更新问题
  问题解决 在读取的过程中设置一个排他锁,在 begin 事务里, select 语句中增加 for update 后缀,这样可以保证别的事务在此事务完成commit前无法操作记录

7 快照的实现

1 事务开始时会向mysql申请一个transation id
 2 事务中每行的变更被称为一个版本
 3 每个版本都会导致trx_id(赋值为row_id)递增,作为标记版本
 4 而数据版本的可见性规则,就是基于数据的 row trx_id...

5 快照是基于库做的

8 id自增长知多少

1 thread_id
    内容 show processlist的第一列就是thread_id,用来进行标注
 2 trx_id
   内容 用来维护一致性读场景
3  xid
   内容 用来维护二次提交的事务一致性(redo and binlog必须xid一致)

9  在生产环境中究竟是用RR还是RC模式

这取决与你的业务查询,因为RR和RC模式的根本区别在于采用select获取结果的不同可能性,如果你的业务依赖于大量的一致性读,就不该采用RC模式,如果只是少量的一致性读,则可以采用rc模式,一致性读用for update实现