MySQL事务管理

目录

事务的隔离级别

不同隔离级别引发的问题

多版本并发控制(MVCC)

3个记录隐藏列字段

undo日志 

Read View

读提交和可重复读的区别


事务( Transaction):由一次或者多次基本操作构成,或者说,事务由一条或者多条 SQL 语句构成。这些语句在逻辑上存在相关性,这一组SQL语句要么全部成功,要么全部失败,是一个整体。

事务的四种属性
原子性一个事务中所有的操作,要么全部完成,要么全部不完成,不会在中间停止,如果在执行过程中发生错误,会回滚为事务开始前的状态
隔离性

防止多个事务并发执行时由于交叉执行而导致的数据不一致。

事务的隔离分为读未提交( Read uncommitted )、读提交 ( read committed )、可重复读repeatable read )和串行化( Serializable

一致性
在事务开始之前和事务结束以后,数据库的完整性没有被破坏。
持久性
事务处理结束后,对数据的修改就是永久的。

事务的隔离级别

读未提交:所有的事物都可以看到其他事物的没有提交的执行结果。可能会引发脏读、幻读、不可重复读等错误。

读提交:一个事务只能看到其他事物已经提交的事物所做的改变。可能引发不可重复读。

可重复读:同一个事物在执行中,多次读取操作所获取到的数据是相同的。可能会引起幻读。(MySQL的默认隔离级别,但是MySQL没有幻读的问题)

串行化:最高的隔离级别,对事务进行排序,使其不可能发生冲突,并在每个读的数据行上面加上共享锁。可能会导致超时和锁竞争,从而使得效率很低。

不同隔离级别引发的问题

脏读:事务A刚向数据库内插入了一条数据,事务B进行了读取,此时B就获取到了A插入的数据,但是A发现他插入的数据是错误的,于是删除了数据,这就导致了B读到的数据是无效的。即事务B读到了不存在的数据。

幻读:数据库在可重复读的时候,可以屏蔽delete、update等操作,但是不能屏蔽insert的数据,这就导致了其他事务在进行读取的时候可能会读到插入的数据,就如同产生了幻觉一样。

不可重复读:事务A读取数据后,事务B提交了操作,事务A再次读取了数据就导致了两次读取到 的数据不同。

不可重复读可能引发的错误:某公司需要根据客户的会员等级发放礼品(假设礼品发放顺序为DCBA),会员甲的等级为D级,在发放完D级礼品后,甲突然把会员等级提升为C级,这时再查询甲的等级就是C级,然后甲就收到了C级的礼品,之后甲又把会员等级提升到了B级,A级,这样甲就收到了ABCD四个等级的礼品。

隔离级别脏读不可重复读幻读加锁读
读未提交×
读提交××
可重复读××××
串行化×××

多版本并发控制(MVCC)

用来解决 读-写 冲突 无锁并发控制 

3个记录隐藏列字段

修改该记录的事务ID DB_TRX_ID 6 byte ,最近修改 ( 修改 / 插入 ) 事务 ID ,记录创建这条记录 / 最后一次修改该记录的事务 ID
隐式主键 DB_ROLL_PTR : 7 byte ,回滚指针,指向这条记录的上一个版本(简单理解成,指向历史版本就行,这些数据一般在undo log 中)
回滚指针 DB_ROW_ID : 6 byte,隐含的自增 ID (隐藏主键),如果数据表没有主键, InnoDB 会自动以 DB_ROW_ID 产生一个聚簇索引

 由此就形成了版本链

undo日志 

 由于MySQL的操作是在内存中完成的,所以需要一款缓冲区保存相关数据,并在适当的时候刷新到磁盘中。所以undo日志就是一块内存缓冲区,用来保存日志数据。

Read View

当前读:读取最新的数据,增删改都是当前读。

快照读:(一般而言)就是读取历史版本。

Read View 就是事务进行 快照读 操作的时候生产的读视图,在 MySQL 源码中 , 就是一个类。

//read view的部分结构

m_ids; //一张列表,用来维护Read View生成时刻,系统正活跃的事务ID 
up_limit_id; //记录m_ids列表中事务ID最小的ID(没有写错) 
low_limit_id; //ReadView生成时刻系统尚未分配的下一个事务ID,也就是目前已出现过的事务ID的最大值
creator_trx_id //创建该ReadView的事务ID

从时间线可以看出,事务只能看到他之前的事务所做的操作,并不能预料到之后的时间。

在进行数据的读取时,会进行快照读,记录当前所活跃的事务,这时快照读所记录的所有活跃事务能读取到的最新数据就是进行快照读之前,数据的最后一个版本。

这样由于不同事务所看到的版本不同就产生了隔离性。

读提交和可重复读的区别

可重复读 条件下,用的read view 是第一次读取产生的,之后使用的都是该read view
因为可重复读用的都是一个read view,所以每次读取的数据都是一样的。
读提交条件下,每一次读取都会更新read view
因此每次读取的数据可能会不同。
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值