福州建设网站公司,wordpress文章分享按钮设置,娄底网站制作,有口碑的南昌网站建设Mysql事务 事务概念事务特性事务并发事务隔离级别MVCC多版本并发控制 事务概念
小钢同学今天发工资了#xff0c;赶紧打开招商银行app看看工资到账了没有#xff0c;查看余额300 嗯#xff0c;今天心情好#xff0c;给对象转账50大元买lv包包去#xff0c;最后的结果肯定… Mysql事务 事务概念事务特性事务并发事务隔离级别MVCC多版本并发控制 事务概念
小钢同学今天发工资了赶紧打开招商银行app看看工资到账了没有查看余额300 嗯今天心情好给对象转账50大元买lv包包去最后的结果肯定是小钢同学的钱包余额是250小钢同学对象钱包余额50 转账的整个过程在mysql中涉及到一系列动作下面仔细来看看 现在来考虑一下这个问题如果在第6步的时候更新数据库失败了会发生什么情况
小钢同学的钱包余额为250元小钢同学对象的钱包余额为0元 转账的50元不翼而飞了小钢百思不得其解为此还和对象吵了一架明明钱给转过去了呀对象还说没收到 还好小钢是个技术高超的程序员大佬趁着和对象冷战期去研究了一下数据库事务发现事务可以完美解决这个问题于是赶紧连夜给平台提了bug 数据库中的「事务Transaction」让多个数据库操作要么全部成功要么全部失败不允许出现中间态数据例如上面情况如果第6步更新数据库失败事务会负责回滚小钢转出去的50元会被继续增加回去小钢余额还是拥有300元
事务特性
首先得注意的是并不是所有的mysql存储引擎都支持事务常见的Innodb是支持事务的而MyISAM则不支持事物所以mysql默认的存储引擎是Innodb 事务有以下四大特性
原子性所有操作要么全部成功要么全部失败不允许出现中间态 比如文章开头所说的小钢转账问题如果中间任何一个步骤出现问题事务需要回滚到最初始状态就好比没发生这件事情一样 一致性数据库从一个一致性的状态转移到另一个一致性的状态满足完整性约束 小钢给对象转账之前小钢余额300元对象余额0元总和300元 小钢给对象转账50元以后事务提交完成小钢余额250对象余额50元总和300元 转账前和转账后总和不变这就是一致性 持久性事务一旦提交数据的改变就是持久性的就算磁盘宕机恢复也还是修改后的数据 事物提交后小钢余额250对象余额50元这个数据是一个持久性的状态除非再次修改 隔离性数据库允许多个并发事务同时对其数据进行读写和修改的能力隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致
事务并发
mysql事务核心在于隔离性本文重点讲解一下隔离性 首先还是谈一下事务并发会带来什么问题
脏读如果一个事务「读到」了另一个「未提交事务修改过的数据」就意味着发生了「脏读」现象 事务A和事务B同时开始执行事务A先读取小钢余额是300元事务B紧接着将小钢余额更新为250元此时事务B没有提交事务事务A在这个时候再次查询小钢余额发现变成了250元此时事务B提交事务失败回滚了小钢余额变为了初始300元事务A却还认为小钢余额为250元此时事务A读到的250元数据就是脏数据 不可重复读在一个事务内多次读取同一个数据如果出现前后两次读到的数据不一样的情况就意味着发生了「不可重复读」现象 事务A和事务B同时开始执行事务A读取小钢余额300元然后先去干其他事情了事务B读取小钢余额300元并更新为250元然后成功提交事务此时事务A再次读取小钢余额为250元在同一次事务执行中读取数据不一致这就是不可重复读问题 幻读在一个事务内多次查询某个符合查询条件的「记录数量」如果出现前后两次查询到的记录数量不一样的情况就意味着发生了「幻读」现象 事务A和事务B同时执行事务A负责将所有工资等于100元的员工工资加薪到200元比如此时有5个员工需要加薪事务A完成了更新操作但是还未提交事务事务B此时新增一个新员工的数据工资为100元然后提交事务然后这个时候事务A再次查询工资等于100元的员工发现变成了6个员工就好像发生了幻觉一样这就是幻读 事务隔离级别
事务四种隔离级别
未提交读一个事务未提交时他所做的变更可以被其他事务看到 会发生脏读、不可重复读、幻读 已提交读一个事务提交以后他所做的变更才能被其他事务看到 会发生不可重复读、幻读 可重复读事务开启以后直到提交事务这个时间段所能看到的数据就是事务开启时的数据其他事务变更记录看不到 会发生幻读 可串行化对事务加锁如果发生了读写冲突会等拿到锁的事务提交以后才会继续执行其他事务 可以解决所有事务并发问题 那么可能会有一个问题为什么可串行化可以解决所有事务并发问题为什么数据库不用可串行化隔离级别 原因可串行化需要加锁太慢了对于优秀的开源系统怎能容忍这种效率问题 mysql默认的隔离级别是可重复读虽然有幻读的风险但是概率并不大
MVCC多版本并发控制
mysql的可重复读就是巧妙的借用了MVCC多版本并发控制的思想
针对快照读普通查询select * from table_name通过 MVCC 方式解决了幻读因为可重复读隔离级别下事务执行过程中看到的数据一直跟这个事务启动时看到的数据是一致的即使中途有其他事务插入了一条数据是查询不出来这条数据的所以就很好的避免幻读问题针对当前读select … for update 等语句通过 next-key lock记录锁间隙锁方式解决了幻读因为当执行 select … for update 语句的时候会加上 next-key lock如果有其他事务在 next-key lock 锁范围内插入了一条记录那么这个插入语句就会被阻塞无法成功插入所以就很好了避免幻读问题 快照读是如何使用MVCC多版本控制思想的呢原理是什么 待更新…