MySQL事务实现原理
作者:互联网
转自:https://blog.csdn.net/qq_46312987/article/details/123941617
https://blog.csdn.net/binbigdata/article/details/82938781
什么是事务?
事务是访问和更新数据的程序执行单元,事务中可能含有一个或多个SQL语句,这些语句要么全部执行,要么都不执行
回顾MySQL的逻辑架构与存储引擎
如上图所示,MySQL服务器的逻辑架构从上到下分为三层:
- 第一层:处理客户端连接、授权认证等
- 第二层:服务器层,负责查询语句的解析、优化、缓存以及内置函数的实现、存储过程等。
- 第三层:存储引擎,负责MySQL中数据的存储与提取。MySQL中服务器层不管理事务,事务是由存储引擎实现的,MySQL支持事务的存储引擎有InnoDB,NDB Cluster等,使用最多的就是InnoDB,也是MySQL默认使用的存储引擎,其他引擎不支持事务,比如MyISAM,Memory等。
ACID
原子性(Atomicity)
一个事务可能包含多个SQL语句,原子性就是要保证这些SQL语句要么全部执行,要么全不执行
举个例子:
A想要从自己的帐户中转1000块钱到B的帐户里。那个从A开始转帐,到转帐结束的这一个过程,称之为一个事务。在这个事务里,要做如下操作:
1. 从A的帐户中减去1000块钱。如果A的帐户原来有3000块钱,现在就变成2000块钱了。
2. 在B的帐户里加1000块钱。如果B的帐户如果原来有2000块钱,现在则变成3000块钱了。
如果在A的帐户已经减去了1000块钱的时候,忽然发生了意外,比如停电什么的,导致转帐事务意外终止了,而此时B的帐户里还没有增加1000块钱。那么,我们称这个操作失败了,要进行回滚。回滚就是回到事务开始之前的状态,也就是回到A的帐户还没减1000块的状态,B的帐户的原来的状态。此时A的帐户仍然有3000块,B的帐户仍然有2000块。
我们把这种要么一起成功(A帐户成功减少1000,同时B帐户成功增加1000),要么一起失败(A帐户回到原来状态,B帐户也回到原来状态)的操作叫原子性操作。
一致性(Consistency)
事务在系统完整性中实施一致性,这通过保证系统的任何事务最后都处于有效状态来实现。如果事务成功地完成,那么系统中所有变化将正确地应用,系统处于有效状态。如果在事务中出现错误,那么系统中的所有变化将自动地回滚,系统返回到原始状态。因为事务开始时系统处于一致状态,所以现在系统仍然处于一致状态。
隔离性(Isolation)
并发事务之间互相影响的程度,比如一个事务会不会读取到另一个未提交的事务修改的数据。在事务并发操作时,可能出现的问题有:
- 脏读:事务A修改了一个数据,但未提交,事务B读到了事务A未提交的更新结果,如果事务A提交失败,事务B读到的就是脏数据。
- 不可重复读:在同一个事务中,对于同一份数据读取到的结果不一致。比如,事务B在事务A提交前读到的结果,和提交后读到的结果可能不同。不可重复读出现的原因就是事务并发修改记录,要避免这种情况,最简单的方法就是对要修改的记录加锁,这回导致锁竞争加剧,影响性能。另一种方法是通过MVCC可以在无锁的情况下,避免不可重复读。
- 幻读:在同一个事务中,同一个查询多次返回的结果不一致。事务A新增了一条记录,事务B在事务A提交前后各执行了一次查询操作,发现后一次比前一次多了一条记录。幻读是由于并发事务增加记录导致的,这个不能像不可重复读通过记录加锁解决,因为对于新增的记录根本无法加锁。需要将事务串行化,才能避免幻读。
事务的隔离级别从低到高有:
- Read Uncommitted:最低的隔离级别,什么都不需要做,一个事务可以读到另一个事务未提交的结果。所有的并发事务问题都会发生。
- Read Committed:只有在事务提交后,其更新结果才会被其他事务看见。可以解决脏读问题。
- Repeated Read:在一个事务中,对于同一份数据的读取结果总是相同的,无论是否有其他事务对这份数据进行操作,以及这个事务是否提交。可以解决脏读、不可重复读。
- Serialization:事务串行化执行,隔离级别最高,牺牲了系统的并发性。可以解决并发事务的所有问题。
通常,在工程实践中,为了性能的考虑会对隔离性进行折中。
标签:事务,帐户,提交,块钱,MySQL,原理,1000 来源: https://www.cnblogs.com/pengsay/p/16341508.html