关系型数据库事务ACID特性概述

Posted 大俊Tech

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关系型数据库事务ACID特性概述相关的知识,希望对你有一定的参考价值。

本文旨在站在更高的层次分析和抽象数据库的事务执行原理,和给出一些概念,而不会去分析某一种数据库是怎么做

    通常从数据库的角度来看,数据库中的某些操作的集合被认为是一个独立的单元,比如从顾客的角度来看,转账的过程是一次单一的操作,而在数据库中这是几个操作组成的,显然有一点是最基本你的,这些操作要么全部发声,要么全部不发生,如果出现A账户转出了,但B账户却没有增加,这是不可接受的。
    将一组操作复合为单一的逻辑执行单元的过程称作事务。这组操作要么完全执行,要么完全不执行。即便是数据库系统发生故障的情况下也必须保证事务的正确运行。至于怎么实现的我们后面讨论。

事务的ACID特性

Atomicity,Consistency,Isolation,Durability,事务的这四个特性可以说是老生常谈了。事务由 begin transaction 和 end transaction语句界定,由其之间的SQL语句全体操作组成。举一个mysql的事务代码的例子:

begin transaction transaction_name
save transaction savepoint;                   --创建事务保存点
insert into table_name values (xxx,xxx,...); 
update table_name set column_name = value where condition;
if @@error<>0                         --判断如果两条语句有任何一条出现错误
begin rollback savepoint       -–开始执行事务的回滚,恢复的转账开始之前状态
else                           --如何两条都执行成功
begin commit tran              --执行这个事务的操作
commit transaction transaction_name;

这就是一个典型的事务,将一个插入语句和一个更新语句复合为一个单一的逻辑执行单元,中间如果出现SQL执行失败则执行回滚操作,将数据库状态回滚到保存点,如果都成功则提交事务,最后他们要么都完成,要么都不完成。

Atomicity(原子性)

    事务中的所有操作在数据库中要么都全部正确反映出来,要么完全不反映。因此如果一个事务开始执行,但是由于某些原因失败,则事务对数据库造成的任何可能的修改都需要撤销。无论是因为事务中出现错误的操作导致事务失败,还是操作系统崩溃,或是计算机停止运行,这项基本要求都要成立,保证这点是苦难的,因为事务中某些操作的修改可能仅仅存在于事务运行的主存中,而另一些则已经保存到磁盘上了(其实每一条SQL就是一个小小的事务),但是我们之后会讲述数据库是如何保证这点的,这种 “全或无” 的特性就是 原子性;

Isolation(隔离性)

    事实上,记住一点,事务是并发的执行的,但由于事务是不可分割的单一逻辑执行单元,其中可能有多条SQL语句,因此,数据库必须采取特殊的处理方式来确保事务的正常执行,而不被来自并发执行的数据库操作所干扰结果, 这就是隔离性。就像这样:尽管事务可能并发执行,但数据库保证,对于任何一个事务A和B,在A看来,B或者在A执行之前就执行了,或者在A完成之后开始执行,因此每个事务都感觉不到系统中有其他事务在并发的执行,当然这是最理想的方式,但并不一定是我们想要的,有时候我么为了追求更高的并发度,或是某些场景下我们会采用一种弱一点的隔离性,这就是隔离级别,后面会阐述几种隔离级别。

Consistency(一致性)

    解释一致性是困难的,因为这个词比其他几个词更为抽象,让我们举几个例子说明一致性,一致这个词的中文意思是“趋势相同,没有分歧,前面是什么样的,后面还得是什么样”,例如,我有100块钱,给了你30元,我还有70元,没毛病,这时候数据是一致的,逻辑正确的,但是,如果给了三十,我却只有了50元,那么此时数据就不一致了,还有20不知所终,逻辑上错误了!逻辑上要求我剩下的钱 + 给你的钱 = 我之前拥有的钱才是正确的,这个要求就是一致性要求事务不能凭空创造数据,必须按照事实要求的逻辑正确的方式执行数据操作,这就是事务的一致性,

确保一致性的要求是编写该事务的程序员的责任,一致性要求是程序员根据业务逻辑的上下文环境来确定的。

    确定好了一致性要求,也正确编写好了事务SQL代码,可是由于事务执行过程中发生故障,某些操作没有被执行,数据库中的数据不再能反映出数据库本应该描述的现实世界的真实在状态。我们把这种状态叫做 不一致性状态,反之则是一致性状态。例如A转账50元给B,但是A减去50元之后系统发生故障,事务停止,此时B却没有加上50元,数据就处于不一致的状态了,数据库必须有能力保证这种不一致性在数据库中是不可见的,且最终这种不一致的状态都必须被一个一致的状态代替,那么怎么做呢?这就是需要原子性的原因,如果有了原子性,某个事务的所有操作要么在数据库中全部反映出来,要么全部都不反映,这项工作是由称作 恢复系统 的一个数据库组件处理的,他的基本思路我们会在后面的文章中详细阐述。

Durability(持久性)

    一旦事务成功的完成执行,并且发起事务的用户已经被告知资金转账已经发生,系统就必须保证任何系统故障都不会引起与这次转账相关的数据丢失,一旦事务成功完成,该事务对数据库所做的所有更新都是持久的,即使事务执行完后出现系统故障,这就是持久性。

    计算机系统的故障会导致内存中的数据丢失,但已经写入磁盘的数据绝不会丢失。我们可以确保两条规则以保证持久性

  • 事务做的更新在事务结束之前已经写入磁盘

  • 有关事务已执行的更新信息已写到磁盘上,并且此类信息必须充分,能让数据库在系统故障后重启时能够重新构造数据。

这项工作也是由能够保证原子性的恢复系统完成的。所以恢复系统保证了持久性和原子性。

总结

    清楚的了解事务的ACID特性,以及数据库是如何保证ACID特性的对于日常的开发工作具有极大的辅助意义,能够帮助我们深入分析问题,抓住问题的核心本质。
    上面说了一堆,其实开发中接到比较多的还是隔离性,这里有几个隔离级别需要开发自己掌握并熟练运用。还有就是事务的传播行为,并发控制等几个重要的方面。


以上是关于关系型数据库事务ACID特性概述的主要内容,如果未能解决你的问题,请参考以下文章

深入学习MySQL事务:ACID特性的实现原理

PostgreSQL中的ACID特性介绍

深入学习MySQL事务:ACID特性的实现原理

深入学习MySQL事务:ACID特性的实现原理

深入学习MySQL事务:ACID特性的实现原理

事务--01---事务的ACID特性事务的常见分类