并发问题,
丢失修改,不可重复读,幻读,脏读
- 不可重复读
有个事务T,T读了两次数据,在两次中间有人update/delete了数据,导致T两次读的结果不一致 - 幻读
(在高性能mysql里把这个归为不可重复读)同上读了两次,中间有人insert了一条数据,导致两次结果不一致 - 脏读
即读到其他事务未提交的数据,读到其他事务回滚的数据 - 丢失修改
两个事务先后读改再提交,导致最终结果错误(?)
事务隔离级别有四种,RU,RC,RR和SI
三段锁协议
一段锁:在改前加X锁,T完释放,可解决丢失修改(不可以啊?)
二段锁:读前S锁,读完释放,解决脏读
三段锁,读前S锁,T完释放,解决不可重复读
以上是理论,实际InnoDB的隔离级别的实现与这些大不相同,很多文章也提到了,ANSI规定的四种隔离级别会有漏洞,所以oracle与mysql实际的事务隔离级别的实现与它规定的隔离级别不同
mysql的实现
RC
在RC和RR下都用到了MVCC.
MySQL的读已提交实际是语句级别快照,即快照读的时候读的总是最新的快照.读的策略与可重复读类似。
RC写锁的使用方式。这里不需要GAP LOCK,只使用记录锁(所以会幻读)。并且事务只持有被UPDATE/DELETE记录的写锁(可重复读需要保留全部写锁直到事务结束,而读已提交只保留真正更改的)。
RR
RR下也用MVCC,和RC的区别是它读的是事务开始时的快照.
RR下默认读不加锁而是用快照读,只有写才加锁,读写互不阻塞,但会有Write Skew异常(TODO)。
RC和RR差别是:RC隔离级别下的