事务的四个特性(ACID)
原子性
要么做完,要么啥也别做。实现依赖于undo log 和 redo log。
一致性
节点服务器的数据完整性,指在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。这是说数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性。依赖undo log。
隔离性
你做你的,我做我的。且所做的修改在事务最终提交之前,对其他事务是不可见的。
持久性
敢做敢当,不准反悔。 对于innodb来说,是一个多版本存储引擎,它会保留修改过的行的历史版本信息。信息被存储在表空间(tablespace)中的一种称为回滚段(roll segment)的数据结构中。InnoDB使用回滚段中的信息来实现undo操作(事务回滚),也可以利用回滚段中的信息来创建行的早期版本(一致性读)。依赖于redo log。
数据库的隔离性:
未提交读
READ UNCOMMITTED(RN): 事务中的修改,即使未提交,其它事务也是可见的。因而可能导致脏读。
提交读
READ COMMITTED(RC): 事务中的修改,在未提交前,所做的修改对其它事务是不可见的, 但可能导致不可重复读(同一个事务中多次执行相同查询,结果不一致)。
可重复读
REPEATABLE READ(RR): 同一个事务中多次执行相同查询结果是一致的,但可能存在幻读,MVCC下可以防止幻读。
串行化
SERIALIZABLE(S): 序列化读或写, 可防止幻读。
有RC和RR下才会使用MVCC, 且MVCC只对select操作有效。
在RC级别下: select会读取行的最新的提交版本;而在RR级别下, select只会读取事务开始时的版本,且事务开始时刻指的是一个事务中的第一条查询语句。
表锁
整个表加锁,开销较小。
行级锁
对一行加锁,开销大,支持最大并发处理。
Record Lock
单个行记录上的锁。
Gap Lock
间隙锁,锁定一个范围,但不包括记录本身,只有在RR的时候生效。GAP锁锁住的是B+树的间隙, 它是一种索引锁,可以防止幻读,因为它是锁住一个间隙,一段范围,防止在这个范围里进行插入操作。Gap锁用于可重复读,在快照读时仅mvcc便可起到防止幻读的作用,但是当存在当前读时就需要使用gap锁了
Next-Key Lock
1+2,锁定一个范围,并且锁定记录本身。对于行的查询,都是采用该方法,主要目的是解决幻读的问题,在RR的隔离级别生效
读锁
共享锁(S锁);
写锁
又叫排他锁(X锁)。
读锁是共享的,互不阻塞,读取同一资源互不影响;写锁排他,一个写锁会阻塞其他的读写操作。
一致读视图
select... for update 加X锁(排他锁)
当写操作时,加写锁,资源访问排他。当没有写时,加读锁,读锁互不冲突。写锁比读锁有高优先级。
事务需要进行一致性读操作时,会创建一个Consistent Read View(一致读视图):首先它会记录下最小的还未被使用的事务版本号(trx_sys_t::max_trx_id),称为low limit,且它不可能看到Consistent Read View创建时所有处于active状态的事务所作的修改。