数据库基础(一)事务的ACID

​什么是事务?

在数据库系统里而言,事务是代表一个或者一系列操作的最小逻辑单元,所有在这个逻辑单元内的操作要么全部成功,要么就全部失败,不存在任何中间状态,一旦事务失败那么所有的更改都会被撤销,一旦事务成功所有的操作结果都会被保存。


为什么要有事务?

如果无法直观的从概念上理解事务的话,那我们可以尝试从它解决问题的出发点来了解它,事务机制存在的目的就是无论我们的操作过程中是成功、失败、异常,或者是受到干扰的情况下,事务都能保证我们数据最终的一致性。

为了让大家重视和理解事务的作用,所以我们必须看一个和钱有关的例子:


案例:转账


A账户余额有1000元,B账户余额0元,在这个基础上A向B转账400元,流程如下:

1、查询A账户余额,查看看金额>=400元。
1、查询A账户余额,查看看金额>=400元。
2、满足条件则先从A账户扣款400元(当前A余额=600、当前余额=0)。

没有事务支持的情况下会是什么样?

如果上面每个操作都是独立的,那么任意一个操作的失败都不会影响下一步操作,这样就可能会出现下面几个场景:


情况一:在执行完第2步后,执行第3步系统发生异常失败了,那么最后的结果A余额=600,B账户余额=0;
情况一:在执行完第2步后,执行第3步系统发生异常失败了,那么最后的结果A余额=600,B账户余额=0;


很明显这样直接会导致严重的问题,因为这样的情况下系统会凭空减少或多出钱出来,所以我们需要一套事务机制来容许在异常情况下,能让数据恢复到最初的样子。


有事务支持的情况会是什么样?

其实在这个操作中,转账就是本次一系列操作的最小逻辑单元,只有3个操作都成功了才算转账成功,任何一个步骤失败都算整个转账操作失败,只要其中任意一个步骤执行失败都不会再往下执行,并对已经执行的数据变更进行恢复。


转账开始
1、查询A账户余额,看金额是>=400元 (失败则整个转账失败)。
2、满足条件则先从A账户扣款400元(当前A余额=600、当前余额=0)(失败则整个转账失败)。
3、然后再向B账户增加400元(当前A余额=600,当前B余额=400)(失败则整个转账失败,同时把上一步的扣 款400返还给A账户)。
转账结束


这样在事务的机制下,不管转账成功还是失败系统数据最终都是一致的,钱才不会出现凭空变多或者减少,这也是事务存在的意义。


事务的特性(ACID)

要实现事务的最终目的,需要几种机制组合才能实现,这几种机制就是事务的几个特性,分别是原子性、隔离性、一致性、持久性。用一句话总结来总结这几个特性之间的关系,那就是“一致性是事务的最终目的,而原子性、隔离性、持久性其实都是为了实现一致性的手段”。


1、原子性(Atomicity)

概念:一个事务必须是一系列操作的最小单元,这系列操作的过程中,要么整个执行,要么整个回滚,不存在只执行了其中某一个或者某几个步骤。

对应到上面的转账操作中,原子性就代表(检查余额、转账、到账)三个步骤就是一个整体,少了任何一个都不能称为一次转账,整个过程中检查余额、转账、到账要么整体都执行,要么一个失败就整体失败,绝对不会出现某一个执行成功其他的都执行失败,或者某一个执行失败其他的操作执行成功的情况。


2、隔离性(Isolation)

概念:隔离性是说两个事务的执行都是独立隔离开来的,事务之前不会相互影响,多个事务操作一个对象时会以串行等待的方式保证事务相互之间是隔离的:

小明和小芳各自有一本作业本,如果他们同时去写作业,这时他们都可以在各自作业本上写作业是相互不影响的。但是如果他们两个人只有一本作业本,但是他们都想去写作业怎么办,那么这个时候就只能等一个人先写完作业后,另外一个人才能写,要不然两个人同时在同一个作业本上写作业,那么肯定会乱套。所以这种两个事物操作同一个对象必须隔离开来不能相互影响的特性称为事务的隔离性。


3、一致性(Consistency)

概念:事务要保证数据库整体数据的完整性和业务数据的一致性,事务成功提交整体数据修改,事务错误则回滚到数据回到原来的状态。

如上面转账的案例,如果事务提交成功则A账户减金额,B账户则加对应的金额,数据库总体金额不变只是载体变了。如果事务出错则整体回滚,无论到了上面的哪个步骤A和B的数据都会回到事务开启前的状态保证数据的始终一致。


4、D(Durability)持久性:

概念:持久性是指一旦事务成功提交后,只要修改的数据都会进行持久化(通常是指数据成功保存到磁盘),不会因为异常、宕机而造成数据错误或丢失。



编辑于 2022-05-28 10:50