**面试三 mysql事务隔离**
熊大
话说今天妹子又来了没有废话直接问熊哥你知道事务的四个特性嘛?
我:****必须的ACID
妹子:那你知道事务的隔离机制嘛?
我:必须的(读未提交、读已提交、可重复读、串行)
妹子:现在开启两个事务对同一条sql操作一个对其查询一个对其更新
那么不同事务隔离级别下这个查询出来的值是一样的嘛?那种事务隔离机制是建立在视图上的?
我:
事务: ACID(Atomicity、Consistency、Isolation、Durability,即原子性、一致性、隔离性、持久性)
那么事务提供的能力就是要么保证成功要么失败很干脆。
首先明确一点mysql的性能随着隔离性的提高性能也随之下降。
由上面得知隔离性有四种:
读未提交: 一个事务还没提交时,它做的变更就能被别的事务看到
读已提交:一个事务提交后他做的变更才能被别人看到。
可重复读:一个事务执行中的看到的数据总跟它在启动的时候看到的数据是一致的
串行: 对同一行记录读加锁、写加锁如果有事务访问必须等待上一个事务完成才能执行。
其实这个隔离级别就是针对的是更新语句的在更新的时候另外一个事务过来查询看到的结果是什么?不同的隔离级别看到值是不一样的。
create table X(ID int primary key, c int);
insert into X© values(1);
看下在不同隔离级别下我们看到的V1、V2、V3的值是多少?
读未提交:
V1是2那么V2、V3呢? 在查询V2、V3的值时B的事务没有提交但是它也能看见值是发生变化。所以说V2、V3 均是2。
备注也就是说更新时候只要更新结果事务虽没有提交但是我是允许你看到结果的
读已提交
顾名思义也就是说只有事务提交了才能看到。也就是说只有B的事务提交了A才能看到真正的结果那么V1是1,V2,V3则是2
可重复读
这个有点不好理解他是事务执行期间看到的值是一样的除非提交了事务这个值才发生改变那我们看上图开启事务的时候它查出来的值是1那么V1是1。V2虽然在B提交了事务之后****但是A这个事务并没有提交所以说V2的值也是1。最后V3是2因为A最后提交了事务。
串行
串行的意思大概就是天上地下唯我独尊吧。
则在事务 B 执行“将 1 改成 2”的时候,会被锁住。直到事务 A 提交后,事务 B 才可以继续执行。所以从 A 的角度看, V1、V2 值是 1,V3 的值是 2。
总结:
读未提交:别人改数据的事务尚未提交,我在我的事务中也能读到。
读已提交:别人改数据的事务已经提交,我在我的事务中才能读到。
可重复读:别人改数据的事务已经提交,我在我的事务中也不去读。
串行:我的事务尚未提交,别人就别想改数据。
在隔离级别不同读到的值也是不一样的为什么会不一样呢答案是视图。
在“可重复读”隔离级别下,这个视图是在事务启动时创建的,整个事务存在期间都用这个视图。
在“读提交”隔离级别下,这个视图是在每个 SQL 语句开始执行的时候创建的
串行、读未提交没有视图
隔离级别如何实现:回滚日志
拿重复读隔离级别举例:
每更新一次就会记录一个回滚日志如果你的事务提交完毕mysql则会自动删除回滚日志。
如果有一个长长的事务画面太美了不可想象 假设这个事务A是上午10点开启
10点20事务B过来修改,11点事务C过来修改12点事务D过来修改 而事务A迟迟得不到提交
那么这个视图将会保存一个一个多小时并且回滚日志也得不到删除。这样就占据了mysql大量的空间很可能将他拖垮。
查询长事务sql
select * from information_schema.innodb_trx where
TIME_TO_SEC(timediff(now(),trx_started))>?