拾遗-数据库事务的四特性
最近对事务的四个特性有了新的认识,记录一下。
ACID特性
事务的四个特性
程序的本质是对现实生活的模拟,现实世界中有很多约定好的不可变更的规则,比如两个人交易,一手交钱一手交货,不存在交了钱却没有交货的情况。但是程序却很容易出现这种情况,比如交钱之后断电了,程序崩溃了等。而事务就是为了解决这一类问题产生的。
事实上,transaction这个词在英语环境中的意思本身就是交易、合同的意思,至于事务,这是啥不明所以的词。。
原子性(Atomicity)
原子性表示在同一个事务中的一组小操作整体是不可分割的。要么全部成功要么全部失败,不会结束在某个中间状态。
隔离性(Isolation)
数据库允许多个事务并发操作同一个数据。
隔离性表示处在两个事务中的操作在事务提交之前是隔离的,互不感知互不影响。
事务隔离分为不同级别,包括未提交读(Read uncommitted)、提交读(read committed)、可重复读(repeatable read)和串行化(Serializable)——wiki百科:ACID
比如一个余额为100的银行账户在两个自助机上同时取100块,只有一个能成功。
持久性(Durability)
持久性表示事务处理结束后,对数据的修改是永久性的,不会因为系统故障而丢失。
一致性(Consistency)
一致性是一个在很多领域都存在的概念,所以很容易产生歧义。
要搞懂一致性主要是要明确业务的一致性和事务的一致性的差别。
在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设约束、触发器、级联回滚等。——wiik百科:ACID
这段话的意思是事务会保证一组操作前后,数据库从一个正确的状态转移到另一个正确的状态。而什么是正确的状态呢,就是满足所有我们预设的数据库约束。注意这其中的关键在于正确这个概念其实是数据库设计者也就是我们定义的。
wiki百科中给出的解释说明事务的一致性是一个非常具体甚至局限的概念,事务不能保证任何属于业务层面的一致性,比如这个例子:
A账户有一百块,尝试取出两百块转给B,最后A有-100块,B有两百块。
这个例子难道说明事务的一致性失效了么,并不是的,数据库无法感知余额不能为负这个业务逻辑,它认为这个属于正确的状态。(你们抓的是周树人,跟我鲁迅有什么关系?)
现在我们给账户加上必须大于等于0的限制,会发现事务回滚了,也就是数据库发现这个操作违反了事务的一致性,必须让这个事务失败回滚。
以上解释了数据库的一致性,接下来说明为什么业务的一致性会和事务的一致性混淆。
原因是MySQL的约束效率和使用场景无法满足我们所有的业务需求,很多保证一致性的操作都在业务层做了,数据库层很少用触发器去校验插入的数据是否正确。久而久之业务的一致性就和数据库的一致性混为一谈了。
事务的状态流转
参考:
https://www.zhihu.com/question/31346392
掘金小册:《MySQL 是怎样运行的:从根儿上理解 MySQL》