MySQL 是支持多事务并发执行的,否则来一个请求处理一个请求,处理一个人请求的时候,别的人都等着,这网站就别做了,用户都要砸键盘了。
这里就有一个问题了:一个事务在写数据的时候,另一个事务要读这行数据,该怎么处理?一个事务在写数据,另一个数据也要写这行数据,又该怎么处理这个冲突?其实吧,为了解决这些问题,MySQL 可以说是煞费苦心,使用了 MVCC 多版本控制机制、事务隔离机制、锁机制等。
你一定听过事务可以分成 4 个隔离级别:读未提交、读已提交、可重复读、串行化。上一篇文章「从一个 update 语句开始,来看看 InnoDB 的底层架构原理」中提到的 InnoDB 存储引擎,默认的隔离级别就是是可重复读 REPEATABLE READ。
🤔 到这里,不知道你有没有产生几个疑问?
我们知道有事务隔离这回事儿,那为什么要隔离?为什么隔离还不够,还要分多个级别? 事务隔离级别解决了什么问题?没有解决什么问题? MySQL 是如何实现这几个隔离级别的呢?它们底层的工作原理是什么呢?
多个事务并发执行,是怎么一个场景呢?
commit
,执行失败就要 rollback
。begin; # 开始事务
insert into runoob_transaction_test value(5);
insert into runoob_transaction_test value(6);
commit; # 提交事务
或者
rollback; # 回滚事务
写冲突,多个事务同时对缓存页里面的一行数据进行更新,允许谁来写?这个冲突要怎么解决?可不可以用锁来解决? 读写冲突,一个事务在写数据,别的事务过来读数据了,这个时候要怎么办?
脏写
脏读
事务 A 先写数据,把一行数据的值从 null 改成了 A,同样事务 A 并没有提交; 然后事务 B 过来读了,它读到的值自然是 A 喽; 接着事务 A 又回滚了!回滚之后值就要从 A 变回到 NULL; 事务 B 再去读的时候读到的就是 NULL 了
不可重复读
事务 A 先去读一行数据,读到值是 A; 事务 B 去修改数据,改成了 B。这里和前面不一样的地方就在,事务 B 它还提交了,不回滚了。 事务 A 第二次去读,读到的是 B,和第一次读到的 A 不一样。
幻读
事务 A 里有一个条件查询的语句 select name from t where id > 10
,它进行了一次范围查询,查到了 10 行数据;然后事务 B 网里面加入了一批数据 事务 A 再查的用条件查询语句查询的时候,发现查到了 15 条,其中 5 条是之前没见过的。这个事务 A 以为自己出现幻觉了,怎么会多出这么些个数据?这就是幻读了。
思考题:事务隔离如何解决这些问题?
我们知道有事务隔离这回事儿,那为什么要隔离?为什么隔离还不够,还要分多个级别? 事务隔离级别解决了什么问题?没有解决什么问题? MySQL 是如何实现这几个隔离级别的呢?它们底层的工作原理是什么呢?
转载于:http://mp.weixin.qq.com/s?__biz=MzI5MzQ2MDg4Nw==&mid=2247483812&idx=1&sn=dc24a2c69481b27b08da6199be654e07&chksm=ec708f5cdb07064a1f00f12a9fbfa5e278b0721d7d766c0c189d9e05250a1255557313a63a4b#rd