MySQL事务和锁
前言
一、ACID特性
在关系形数据库中,一个逻辑单元要成为事务,必须满足4个特性。即所谓的ACID:原子性、一致性、隔离性和持久性。
1.原子性
原子性:事务是一个原子操作单元,对其的修改,要么全部执行,要么全部不执行。修改—》Buffer Pool修改—》刷盘。
- 事务提交了,如果此时Buffer Pool的脏页没有刷盘,如何保证修改的数据生效? Redo
- 如果事务没提交,但是Buffer Pool的脏页刷盘了,如何保证不该存在的数据撤销?Undo
每写一个事务,都会修改BufferPool,从而产生响应的Undo/Redo日志,在bufferpool中的页被刷到磁盘之前,这些日志信息都会先写入到日志文件中,如果Bufferpool中的脏页没有被刷成功,此时数据库挂了,那么数据库再次启动之后可以通过redo日志恢复数据;如果脏页刷新成功,此时数据库挂了,就需要通过undo来实现了。
2.持久性
持久性就是数据一单提交了就会,它对数据库的改变应该是永久性的,后续的操作或故障不应该对其有任何影响,不会丢失。
如下图所示,一个“提交”动作触发的操作有:binlog落地、发送binlog、存储引擎提交、flush_logs.check_point、事务提交标记等。
3.隔离性
隔离性:指的是一个事务在执行的时候没有受到其他事务干扰,即一个事务内部的操作及使用的数据对其他的并发事务是隔离的。
InnoDB支持的隔离性有四种,隔离性从高到低分别是:读未提交、读提交、可重复读、可串行化。
4.一致性
一致性:指的是事务开始之前和事务结束之后,数据库的完整性限制未被破坏。一致性包括两个方面的内容,分别是约束一致性和数据一致性。
3. 约束一致性:创建表结构时所指定的外键、check、唯一索引等约束。
4. 数据一致性:是一个综合性的规定,因为它是由原子性、持久性、隔离性共同保证的结果,而不是单单依赖于某一种技术。
一致性也可以理解为数据的完整性。数据的完整性是通过原子性、一致性、隔离性、持久性来保证的,而这三个特性又是通过Redo/Undo来保证。逻辑上的一致性,包括唯一索引、外键约束、check约束
二、事务控制的演进
1.并发事务
事务并发处理可能会带来一些问题,比如:更新丢失、脏读、不可重复度、幻读等。
- 更新丢失
当两个或者多个事务更新同一行记录,会产生更新丢失现象、可以分为回滚覆盖和提交覆盖。 - 脏读
一个事务读取到另一个事务修改但未提交的数据。 - 不可重复读
一个事务中多次读取同一行记录不一致,后面读取的跟前面读取的不一致。 - 幻读
一个事务中多次按相同条件查询,结果不一致,后面查询的结果和前面查询的结果不同,多了或少了几行记录。
2.排队
全局加锁,序列化执行完所有事务。数据库在某个时刻只处理一个事务操作,特点是强一致性,处理能力低。
3.排它锁
引入锁之后会使用排它锁处理并发事务,涉及到数据时,会使用排它锁 将数据锁住。在整个事务结束之前,锁是不会被释放的。
4.读写锁
读和写操作:读读、写写、读写、写读。
读写锁就是进一步细化粒度,区分读操作和写操作,让读和读之间不加锁,这样下面的两个事务就可以同时被执行了。