数据库事物
- 数据库事物是啥:由有限数据库操作序列构成,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位
事物四大特性
- 原子性(Atomicity)(事物操作要么全部执行,要么全部不执行)
- 一致性(Consistency)(事物开始前到事物结束后,数据不被破坏)
- 隔离性(Isolation)(事物之间是相互隔离的,事物不受其他多个事物的影响,多个并发事物需要互相隔离)
- 持久性(Durability)(事物提交之后,事物对数据库所做操作应该是永久保存)
事物并发问题
- 脏读:一个事物读取到另一个事物修改过的已提交的数据
- 幻读:一个事物搜索读取,未提交之前,读取到其他事物insert、delete、update的数据
- 不可重复读:同一个事物多次读取,读取到不同的数据内容
事物四大隔离级别
- 读未提交 :只限制两个事物不能同时修改,一个事物修改后,即使未提交,任然能被另一个事物读取到
- 脏读问题
- 重复读问题
- 幻读问题
- 读已提交 :一个事物只能读取到其他事物已提交的数据,解决脏读
- 重复读问题
- 幻读问题
- 可重复度 :读取数据,其他事物不可进行修改,解决重复读
- 幻读问题
- 串行化 :串行化顺序执行,解决脏读、重复度、幻读,加锁实现事物隔离性
- 频繁加锁,导致数据无法修改,降低数据库性能
多版本并发控制(MVCC)
- 定义:实现对数据库的并发访问
- 事物版本号 :数据库自增长事物ID
- 用来判断事物执行先后顺序
- 隐式字段
- trx_id:事物ID,必须的
- row_id:递增行ID,非必须,6字节,没有主键,非null唯一键出现
- roll_pointer:回滚指针,指向回滚段undo日志
- undo_log(回滚日志) :记录数据被修改前的信息
- delete数据,undo_log会记录insert数据
- update数据,则记录相反update数据
- 用途
- 事物回滚时,保证原子性和一致性
- 用于MVCC快照读
- 版本链 :多个事物并行操作某一行数据,该行数据修改会产生多个版本,通过回滚指针(roll_pointer)形成一个链表
- update user set name ="张三" where id = 1;
- 1、获取一个事物ID:100
- 2、修改user表前的数据,拷贝到undo_log
- 3、修改user表中id为1,将name改成"张三"
- 4、修改后事物ID:101改成当前版本号,并回滚指针(roll_pointer)指向undo_log日志
- 快照读、当前读
- 快照读:读取的是记录数据的可见版本,不加锁
- 当前读:读取的是记录数据的最新版本,显示加锁
- Read View :事物执行SQL产生的读视图。
- 有何用:用来做可见性判断,即判断当前事物可见哪个版本的数据
- 如何保证可见性:
- m_ids:未提交的读写事物ID,数据结构是List
- min_limit_id:生成Read View时,读写事物中最小的事物ID,即m_ids列表中的最小值
- max_limit_id:生成Read View时,分配给下一个事物ID值
- creator_trx_id:创建当前Read View的事物ID。
- 匹配条件规则
- trx_id<min_limit_id,生成该版本事物在Read View前,可被当前事物访问
- trx_id>=max_limit_id,生成该版本事物在Read view后,不可被当前事物访问
- min_limit_id=<trx_id<max_limit_id
- m_ids包含trx_id,代表Read View生成时刻,事物还未提交,如果数据的trx_id = creator_trx_id,表明数据自己生成,可见
- m_ids包含trx_id,代表Read View生成时刻,事物还未提交,数据的trx_id != creator_trx_id,表明数据不是自己生成,不可见
- m_ids不包含trx_id,代表事物在Read View生成前已经提交,修改的结果,可见
MVCC实现原理
- 查询一条记录,基于MVCC的流程
- 1、获取事务版本号,即事务ID
- 2、获取Read View
- 3、查询得到的数据,跟Read View中的事物版本号进行比较
- 4、不符合Read View可见性规则,需要对比undo_log中历史快照
- 5、返回符合规则的数据