事务概念
事务就是一组DML语句组成,这些语句在逻辑上存在相关性,这一组DML语句要么全部成功,要么全部失败,是一 个整体。
一个完整的事务,绝对不是简单的 sql 集合,还需要满足如下四个属性(ACID):
原子性(Atomicity):一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环 节。
一致性(Consistency):在事务开始之前和事务结束以后,数据库的完整性没有被破坏。
隔离性(Isolation):数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时 由于交叉执行而导致数据的不一致。
持久性(Durability):事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
innodb支持事务,而myisam不支持事务。
事务提交方式
事务的提交方式分为手动提交 和自动提交
手动提交是执行事务的时候,需要手动执行事务的begin和commit
自动提交是在执行单sql语句时,只需执行sql语句,mysql自动完成事务的begin和commit
事务的隔离级别
隔离性理解:为了保证事务执行过程中尽量不受干扰
读未提交【Read Uncommitted】: 在该隔离级别,所有的事务都可以看到其他事务没有提交的执行结果。
读提交【Read Committed】 ::一个事务只能看到其他的已经提交的事务所做的改变。
可重复读【Repeatable Read】:它确保同一个事务,在执行中,多次读取操 作数据时,会看到同样的数据行。
串行化【Serializable】:: 这是事务的最高隔离级别,它通过强制事务排序,使之不可能相互冲突。它在每个读的数据行上面加上共享锁。
查看和设置隔离性
mysql> SELECT @@global.tx_isolation; --查看全局隔级别
mysql> SELECT @@session.tx_isolation; --查看会话(当前)全局隔级别
mysql> SELECT @@tx_isolation; --默认同上
设置隔离级别SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}
MVCC(多版本并发控制)
3个隐藏字段
DB_TRX_ID :6 byte,最近修改( 修改/插入 )事务ID,记录创建这条记录/最后一次修改该记录的事务ID
DB_ROLL_PTR : 7 byte,回滚指针,指向这条记录的上一个版本(简单理解成,指向历史版本就行,这些数据一 般在 undo log 中)
DB_ROW_ID : 6 byte,隐含的自增ID(隐藏主键),如果数据表没有主键, InnoDB 会自动以 DB_ROW_ID 产生一 个聚簇索引
补充:实际还有一个删除flag隐藏字段, 既记录被更新或删除并不代表真的删除,而是删除flag变了
undo日志
undo日志记录历史版本,保存历史数据。即保存更新前的记录。
Read View
当前读:读取最新的记录,就是当前读。增删改,都叫做当前读,select也有可能当前读,比如:select lock in share mode(共享锁), select for update
快照读:读取历史版本(历史版本存在undo日志里边),就叫做快照读。
Read View就是事务进行快照读操作的时候生产的读视图 (Read View),在该事务执行的快照读的那一刻,会生成数 据库系统当前的一个快照,记录并维护系统当前活跃事务的ID(当每个事务开启时,都会被分配一个ID, 这个ID是递增 的,所以最新的事务,ID值越大)。
Read View的本质是用来进行可见性判断的。即当我们某个事务执行快照读的时候,对该记录创建一个 Read View 读视图,把它比作条件,用来判断当前事务能够看到哪个版本的数据,既可能是当前最新 的数据,也有可能是该行记录的 undo log 里面的某个版本的数据。
m_ids; //一张列表,用来维护Read View生成时刻,系统正活跃的事务ID
up_limit_id; //记录m_ids列表中事务ID最小的ID(没有写错)
low_limit_id; //ReadView生成时刻系统尚未分配的下一个事务ID,也就是目前已出现过的事务ID的最大值+1(也没有写错)
creator_trx_id //创建该ReadView的事务ID
RR和RC的本质区别
在RC隔离级别下,是每个快照读都会生成并获取最新的Read View;
而在RR隔离级别下,则是同一个事务中的第一个快照读才会创建Read View, 之后的快照读获取的都是同一个Read View。
正是RC每次快照读,都会形成Read View,所以,RC才会有不可重复读问题。