这一章节主要是介绍了事务的必要性,四要素,即(ACID),隔离级别,死锁,事务,多版本并发控制。
其中事务必要性我这里不会再提到,文中举了个银行转账的例子。
四要素
四要素,原子性,一致性,隔离性,永久性。只有满足了这四个要素,才能称得上是一个完整的事务概念。
原子性保证了程序要么全部执行,要么全部不执行。
一致性保证了程序即使在事务途中崩溃,数据也不会因事务中此前的操作而改变。
隔离性保证了在并发状态下,其他用户是看不到事务过程中的数据改变的。
隔离级别
永久性保证了即使事务提交了,然后程序崩溃,该事务产生的数据也不会被改变。
隔离级别我只记录可重复读级别,因为这是 Mysql 默认的隔离级别。大多数数据库软件的隔离级别是读取提交内容级别。
该默认级别解决了脏读(别的程序能读到正处于事务中且数据已经发生改变后的值),但是会有幻读情况。而 Innodb 存储引擎,通过多版本并发控制机制,解决了幻读问题。
以上两种,隔离级别和四要素我们暂时不用考虑太多,因为在实际的业务流程中,我们很少去修改隔离级别,也不会影响我们的编码。Mysql 已经默认为我们解决了很多
死锁
死锁就不一样了,死锁问题在并发高的事务性的系统中,是无法避免的一个问题。需要我们在设计编码的时候,多做判定。
然而 Innodb 有自己解决死锁的一套方案。它可以预知循环的相关性,并立即返回错误。目前 Innodb 处理死锁的方式是,回滚拥有最少排他行级锁的事务。
其他数据库系统也都有相关死锁的一些机制,例如死锁检测,死锁超时机制。否则出现死锁,将无限竞争等待对方释放锁。
事务
默认 Mysql 为自动提交,即每一次的操作都是开启了一个事务,只不过 Mysql 自动给你 Commit 了。这个自动事务我们可以关闭,可以用来测试锁机制和事务。
我们知道,Myisam 是不支持事务的,那如果,我在一个事务中,对一张支持事务的表进行操作,同时也对一张不支持事务的表进行操作,会有什么情况呢?
书中给出了明确的答案,首先这种操作叫做,在事务中混合使用存储引擎。 其次事务是由存储引擎来管理的,并没有在服务器层。
也就是说如果事务处理正常顺利,则没有问题,两张表都会做出对应的改变。但是如果涉及到回滚,那么不支持事务的那张表,则没有能力进行回滚。并且在大多数情况下,Mysql并不会给出一个错误。
书中没有给出解决方案,而是要我们注意选择表引擎。
原文链接: 高性能 Mysql 第一章第三节 事务