MySQL 事务
什么是MySQL事务?
简单的来说,事务是一系列的操作,要么都执行要么都不执行,并不存在中间状态的一说。
事务的四个特性
关系型数据库中,一个逻辑工作单元要想成为一个事物,必须满足四个特性即ACID:原子性,一致性,隔离性,持久化。这四个特性缺一不可;
- 原子性
是指任务是一个独立的操作单元,要么全都是要么全都不是; - 一致性
事务开始之前和事务结束之后,数据库的完整性限制未被破坏; - 隔离性
多个事务并发同时进行时,互相不干扰,每个事务都有它自己的工作空间; - 持久化
指的是事务提交后,数据永久性的保存在磁盘,接下来的一些操作或故障对其不受影响,除非磁盘坏了;
事务隔离级别
-
未提交读(RU,Read Uncommitted)
只要线程执行sql,其他线程都能看见更新后的数据,不管是不是执行commit 。 会产生脏数据。 -
提交读(RC,Read Committed)
需要线程执行力sql的 commit之后 别的线程才能读取到。并发同时写会产生脏数据 A: a不存在 Insert B: a 不存在 insert 会产生两条数据,解决办法是: 1 对写数据,串行化(消息队列,多个消费线程消费) 2 分布式锁 -
可重复度(RR,Repeatable Read)
MySQL默认隔离级别
只能读取到事务开启时的数据, 这个事务内,如果其他线程提交了修改数据,当前事务看不到; -
串行化(Serializable)
一个接着一个执行。 并发效率太低,Io延迟太低。
各隔离界级别区别
MVCC
MVCC是什么?
多版本控制也叫作 MVCC,是指在数据库中,为了实现高并发的数据访问,对数据进行多版本处理,并通过事务的可见性来保证事务能看到自己应该看到的数据版本。
当一个更新操作所对应修改数据的时候,其他事务看到的是这个数据修改之前的副本,这个数据副本存储在Undo log中;
如果没有MVCC,那么更新数据时候其他事务必须等这个事务更新完并且提交事务后才能看到这个数据,读写冲突,这样并发会降低,数据始终是一个版本;
而多版本MVCC不需要使用锁,读写不冲突,极大地提供了系统的并发性能;
MVCC实现原理
f1-f6是数据库字段
在数据记录里,会额外添加3个隐藏字段,row_id,trx_id,roll_ot 分别是行id,事务id以及回滚指针。
其中事务id 每次事务提交成功,自动会+1,回滚指针指向上一个数据版本,当事务需要回滚时候通过这个指针找到数据,此时这个数据会存储在我们的Undo log中,也就是修改之前的副本数据;
当事务进行时候,首先会通过排它锁锁定这一行,将原数据复制一份放到Undo log中,然后记录当前修改后的数据,事务id+1,回滚指针指向Undo log中的数据,最后放入Redo log中;
如果事务不成功,则使用Undo log进行回滚,如果成功,则在特定的时候回删除Undo log日志中的副本数据;
注意:
MVCC 只在 Read Commited 和 Repeatable Read 两种隔离级别下工作,因为MVCC需要变量的提交之前的副本,串行化是单版本,未提交读事务没提交其他事务就已经可见了,此时的副本没任何意义。