ACID作为关系型数据库,MySQL是如何保证最常见的InnoDB引擎的ACID的?(Atomicity)原子性:事务是最小的执行单元,不允许分割。原子性确保动作要么全部完成,要么根本没有效果;(Consistency)一致性:事务执行前后,数据保持一致;(Isolation)隔离:并发访问数据库时,一个事务不会被其他事务干扰。(持久性)持久性:事务提交后。对数据库中数据的更改是持久的,即使数据库发生故障也是如此。隔离先说隔离,首先隔离级别有四种。不解释read未提交。当一个事务还没有提交时,它所做的更改可以被其他事务看到。阅读提交。事务提交后,它所做的更改将被其他事务看到。可以反复阅读。在一个事务中,无论其他事务是否对该数据进行操作,无论该事务是否提交,读取相同数据的结果总是相同的。InnoDB默认级别。序列化事务按顺序执行。每次读取都需要获取表级共享锁。读写会互相阻塞。隔离级别最高,牺牲系统并发性。不同的隔离级别旨在解决不同的问题。即脏读、幻读和不可重复读。隔离级别脏读不可重复读幻读读未提交可以出现是可以出现读提交不允许是是可重复读不允许不允许是序列化不允许不允许不允许不允许然后不同的隔离级别,如何实现隔离,为什么可以不同的东西不会互相干扰吗?答案是锁和MVCC。锁先说说锁,MySQL到底有多少把锁。粒度从粒度上来说,就是表锁、页锁、行锁。表锁包括意向共享锁、意向排它锁和自增锁。行锁由各个引擎在引擎层实现。但并不是所有的引擎都支持行锁,比如MyISAM引擎就不支持行锁。行锁的类型在InnoDB事务中,行锁是通过在索引上锁定索引条目来实现的。这意味着InnoDB只有在按索引条件检索数据时才使用行级锁,否则使用表锁。行级锁也分为共享锁和排他锁两种,以及加锁前需要获取的意向共享锁和意向排他锁。共享锁:读锁,允许其他事务加S锁,不允许其他事务加X锁,即其他事务只能读不能写。选择...锁定共享模式锁定。独占锁:写锁,不允许其他事务加S锁或X锁。插入、更新、删除,用于更新锁。行锁在需要的时候加,不需要的时候不会马上释放,而是等到事务结束才释放。这就是两阶段锁定协议。行锁的实现算法RecordLock对单行记录的锁会一直锁住索引记录。GapLock间隙锁,想想产生幻读的原因,其实行锁只能锁行,但是插入新记录时,需要更新的是记录之间的“间隙”。所以加gaplock来解决幻读。Next-KeyLockGapLock+RecordLock,左开闭。如您所见,LocksforIsolation对锁进行了一般性介绍。有了锁,当一个事务在写入数据时,其他事务无法获得写锁,也就无法写入数据,一定程度上保证了事务之间的隔离性。但是前面说了,加了写锁,为什么其他事务可以读到数据呢?不是不可能获得读锁吗?前面MVCC提到,有了锁,当前事务在没有写锁的情况下不能修改数据,但是仍然可以读取,并且在读取的时候,即使该行数据的其他事务已经修改提交了,同一个值也可以还是要反复读。这就是MVCC,多版本并发控制,Multi-VersionConcurrencyControl。版本链Innodb中行记录的存储格式有一些额外的字段:DATA_TRX_ID和DATA_ROLL_PTR。DATA_TRX_ID:数据行版本号。用于标识最近修改该行记录的事务id。DATA_ROLL_PTR:指向该行的回滚段的指针。该行记录的所有旧版本在undolog中以链表的形式组织。undolog:记录数据修改前的日志,后面会详细介绍。ReadView在每条SQL语句开始时创建,有几个重要的属性:trx_ids:当前系统中活跃的(未提交的)事务版本号的集合。low_limit_id:创建当前读取视图时的“当前系统的最大事务版本号+1”。up_limit_id:创建当前读取视图时“系统当前处于活动事务最低版本号”。creator_trx_id:创建当前读视图的事务版本号;开始查询现在开始查询,一个select来了,找到一行数据。DATA_TRX_ID
