子网站域名ip地址查询,中山专业找人公司,农村建设设计网站,怎样查看网站开发1.四大特性
首先#xff0c;事务的四大特性#xff1a;ACID#xff08;原子性#xff0c;一致性#xff0c;隔离性#xff0c;持久性#xff09;
在InnoDB引擎中#xff0c;是怎么来保证这四个特性的呢#xff1f;
持久性是通过 redo log #xff08;重做日志事务的四大特性ACID原子性一致性隔离性持久性
在InnoDB引擎中是怎么来保证这四个特性的呢
持久性是通过 redo log 重做日志来保证的原子性是通过 undo log回滚日志 来保证的隔离性是通过 MVCC多版本并发控制 或锁机制来保证的一致性则是通过持久性原子性隔离性来保证
然后的话我们这次重点讲一下事务的隔离性。
2.并发事务会带来哪些问题 MySQL是允许多个客户端连接的这样就会导致MySQL同时处理多个事务的情况。
那么就会出现以下三个问题脏读不可重复读幻读
脏读A事务读到了B事务还未提交且修改过的数据。 比如A第一次读某人卡里的余额为100然后A把这个余额修改为200但是不提交事务此时B正好也来读取余额得到200然后A把这个修改进行了回滚100那么B读到的就是脏数据了。
不可重复读A事务前后两次读的数据不一致 比如A第一次读某人卡里余额100然后B来把这个余额进行了修改为200并且提交了事务那么A再一次读取卡里余额就变成200了前后两次读取的数据不一致。 幻读A事务多次查询某个条件的记录数量前后两次查询得到的记录数量不一致。 比如A第一次读取余额大于100的用户有5个然后此时B来插入了一条数据余额为150并提交了事务然后A第二次读取余额大于100的用户变成了6个前后两次读取的记录数量不一致。 3.事务的隔离级别
3.1.四种隔离级别
那么针对上面的三个问题SQL标准提出了四种隔离级别来规避这些现象分别是
读未提交read uncommitted指一个事务还没提交时它做的变更就能被其他事务看到读提交read committedRC指一个事务提交之后它做的变更才能被其他事务看到可重复读repeatable readRR指一个事务执行过程中看到的数据一直跟这个事务启动时看到的数据是一致的MySQL InnoDB 引擎的默认隔离级别串行化serializable 会对记录加上读写锁在多个事务对这条记录进行读写操作时如果发生了读写冲突的时候后访问的事务必须等前一个事务执行完成才能继续执行 对于上面四种隔离级别每个级别还存在的问题有如下 所以要解决脏读现象就要升级到「读已提交」以上的隔离级别要解决不可重复读现象就要升级到「可重复读」的隔离级别要解决幻读现象不建议将隔离级别升级到「串行化」。 这是因为MySQL的InnoDB引擎在可重复读的级别下很大程度的规避了幻读现象不是完全规避我们在后面重点讲可重复读这一块。 3.3.可重复读RR是如何工作的 可重复读级别是在启动事务之后第一次读取数据时生成一个Read View以后的本事务中每次普通查询语句都会依据这个Read View来获取数据。 3.4 读已提交RC是如何工作的 读已提交级别是在启动事务后每次读取数据时都会生成一个新的Read View。 4.可重复读怎么很大程度解决幻读现象
4.1针对普通select语句快照读 是通过MVCC的方式解决了幻读因为RR级别下开始事务后在执行第一个查询语句就会创建一个Read View后续的查询语句都是在这个Read View的基础上来得到数据的。所以即使中途有其他事务插入了新记录那么也是查不出来这个新数据的。 4.2针对select..for update语句(当前读 MySQL 里除了普通查询是快照读其他都是当前读比如 update、insert、delete这些语句执行前都会查询最新版本的数据然后再做进一步的操作。
那么如果在当前读的情况下没有加锁那就会出现幻读现象如下 所以InnoDB引擎为了解决 “在可重复读隔离级别下使用当前读” 而导致的幻读问题就引出了间隙锁。 间隙锁顾名思义是在一个范围之间加锁那么在这个范围之内其他事务就无法进行增删改操作了。 假设表中有一个范围 id 为35间隙锁那么其他事务就无法插入 id 4 这条记录了这样就有效的防止幻读现象的发生。 然后我们举个具体的例子 事务A执行了这条sql语句之后就会对表中的记录加上id范围为2∞] 的next-key lock
这个next-key lock是间隙锁记录锁的组合锁的是左开右闭的区间。 然后事务B在执行sql语句的时候被事务A加的next-key lock给阻塞了那么事务B就会生成一个意向锁等待事务A提交之后再进行插入操作这样就避免了因为B事务插入新数据而导致A事务出现幻读的情况。 5.可重复读级别下幻读被完全解决了吗 通过上面两种情况所做的处理可以说是很大程度上避免了幻读现象但是还没有完全解决幻读现象。
例如
5.1.可重复读级别下幻读情况1
A开启事务并且查询id5的数据不存在。B开启事务插入一条id5的数据并提交事务。A直接进行update操作修改id5的数据此时如果再次执行查询id5的操作那么就会查询到id5的数据了 这种情况就是在A开启事务后通过普通的sql语句生成了一个Read View,之后事务B向表中插入新数据并提交。紧接着事务A对id5的数据进行update操作我们前面提到要进行update操作就必须获取到当前读那么这样的话就会导致事务A再次查询的时候查询的就是最新的数据就会出现幻读了。 5.2.可重复读级别下幻读情况2
A开启事务然后执行select * from t_test where id 100 快照读得到3条记录。B开启事务往里面插入了一个 id200 的记录并提交事务。A继续执行select * from t_test where id 100 for update (当前读得到4条记录。 这种情况就属于A开启事务后没有马上执行select...for update操作导致第一次读取数据时没有加next-key lock从而导致B事务插入了新数据。 6.总结
事务的四大特性ACID(原子性一致性隔离性持久性持久性-RedoLog 一致性-UndoLog 隔离性-MVCC || 锁 持久性-前三个一起保证并发事务带来的危害脏读可重复读幻读四种隔离级别读未提交读已提交(RC)可重复读(RR)串行化可重复读解决可重复读隔离级别默认隔离级提出的避免幻读的方案
针对快照读普通 select 语句是通过 MVCC 方式解决了幻读。生成快照读后续的读都是基于第一次的快照读来获取数据针对当前读select ... for update 等语句是通过 next-key lock记录锁间隙锁方式解决了幻读。 备注图片摘抄自小林coding如有侵权联系删除。