InnoDB支持事务,其它的引擎不支持事务。
1、事务并发问题
多事务并行带来的3个问题:
1)脏读。事务A读到了事务B写入但是还没有commit的数据。
2)不可重复读。事务A先后读到了事务B没提交前、提交后的数据,两份数据不一样。
3)幻读。事务A先后读到了事物B没插入数据前,和插入数据提交后数据。
2、事务隔离级别
多事务并行问题的解决方法,通过设置事务隔离级别来解决:
1)不提交读。不提交就读取,这种隔离级别三个问题都解决不了;
2)提交读。事务B提交了以后,事务A才能读,这种隔离级别解决了脏读的问题;
3)可重复读。一个事务执行过程中,看到的数据都是一样的。这种隔离级别解决了脏读和不可重复读的问题;
4)序列化读。一个事务执行时,加了全表数据的行锁和间隙锁,其它事务等锁解锁以后,才能读。
3、MVCC
事务实现MVCC的过程:
1)每个事务都有一个事务ID;
2)事务开始的时候,会找到当前已提交的最大的事务ID(事务ID是自动递增的),作为这个事务的一致性读视图的事务ID;
3)事务在更改一行数据时,会把更改前的数据和之前的ROW事务ID放到undo log里面,再把更改后的数据和更改的事务ID放到Undo log里面;
4)事务在查询行数据时,如果这行数据是事务一致性读视图的事务ID之前动过的数据,那么直接读取;如果是之后的数据,说明之后又有其它事务动过这行数据了,我们只取一致性读视图的行数据,不取新的数据,所以我们根据undo log来算出一致性读视图的数据,返回。
4、RR与RC使用MVCC
4个事务隔离级别,只有RR与RC使用了MVCC。
快照读时,RR事务内一致性读视图的事务ID不会变,一直是最开始那个,所以实现了不可重复读;RC事务内每次读的时候,都会把一致性读视图的事务ID更改成最新提交的事务的事务ID,所以就不能做到不可重复读。
当前读时,RR使用next-key lock来避免幻读,而RC因为没有GAP锁,所以不能避免。
5、快照读与当前读
这两个概念只会在MVCC里面才存在。
快照读是指读的是MVCC生成的read view,而不是真实最新的数据,read view不是一份真实的数据,而是根据当前最新的数据和undo log计算出来的。
当前读是指直接读当前最新的数据。
6、长事务
Mysql应当尽量避免长事务,长事务会带来很多危害:
1)二阶段锁,只有等事务提交才能释放锁,长事务会导致锁资源的阻塞;
2)事务过程中会生成undo log,过长的的事务会生成大量的undo log,影响快照读的执行效率;
3)事务过程中会生成大量的bin log,这些Binlog等commit的时候才会传输给从库,长事务会导致主从库延迟太大。
7、事务隐式提交
mysql的事务会有隐式提交的情况,具体为:
在一个事务当中,执行ddl操作,会隐式地提交事务。
因此,dml操作和ddl操作造成不要写在一个事务里,不然这个事务就有问题了,不再是一个事务,没法回滚。