对事务一致性的理解

Posted 技术无产者

tags:

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

            原子性,隔离性,持久性这三个特性是为了约束事务最终实现数据的一致性,如果A给B转2000 需要两条SQL (updateA money-2000 updateB money+2000),如果不开启事务,并且在只执行第一条updateA语句时断电,自然就不会在执行第二条updateB语句,这时事务就不是 一致性的了,如果开启事务,由于事务的原子性,如果两条语句没有都执行成功,就会回退,不会出现数据不一致的情况,所以这里通过事务的原子性来保证了事务的一致性。
     当两个事务同时对同一行数据update时,后一个事务执行update后不会往下运行,会等上一个事务提交/回滚后才往下执行,这是四个级别都会出现的问题,因为当一个事务修改了,但没有提交,另一个事务接着对这行数据修改,万一上个事务没有提交而是回退就影响了数据的一致性。这和幻读不是一回事,这是对同一行数据操作会串行,而幻读是事务之间的串行。
可以在再结合下面引自知乎的一个回答来理解:

要想真正弄清楚这个问题,那是必须要把数据库理论中的事务机制从头开始看起,牵扯的内容比较多。

当然,如果只是想粗略的了解下,我就来举个例子吧——当然不可能太严谨。

假设我们10个人,每人有一个账号,里面有钱,可以转来转去,这组成了一个小型的数据系统,那么什么叫数据一致性?这是由你自己来定义的,比较通用的就是:这10个人的账号金额总数不变——满足这一条件,就叫数据一致,不满足,就叫数据不一致,或者在分布式的环境下,有一个数据在几个地方都保存了,那么任何时候,这几个地方的数据都必须相同,这也叫一致性。

现在我们就这个简单的一致性规则:10个人的账号金额总数不变。假设初始的时候每个人账号里有一万,A账号往B账号里转5000,这时候数据库要执行两行代码:

A:减去5000

B:加上5000

在执行完第一行代码的时候,这时候数据是不满足一致性条件的!必须要执行完第二行代码,数据才恢复到一致性的状态!换而言之,数据库中的数据是经常处于不一致的状态,这是不可避免的,因此我们提出了事务的概念,用于检测数据库中的数据是否处于一致性状态——如果数据库中有没有执行完的事务,那就是不一致的,否则,就是一致的。

上面的例子只是最简单的情况,实际的运用中要复杂得多,比如前面提到的分布式系统:某个数据存在了三个服务器上,现在要更新,就必须保证三个服务器上全都更新好,如果有一个没有成功,那么其他两个也应该维持不变,这又涉及到网络通信等问题,非常的折腾。

——————————————————————————————————————

评论中有提到了原子性,其实原子性与一致性是两个完全不同的概念,当然他们的联系也很紧密。

还是用上面的这个例子:

为了保证一致性(即10个人 的账号金额总数不变),那在我写代码的时候,如果写了代码:

A=A-5000;

那就必须要写上

B=B+5000,或者是C=C+5000,这样的代码才能保证了数据库的一致性状态。

那什么是原子性?

就是将上面的两行代码合成为一个事务,要么全做,要么全不做。


 

事务的隔离性是指:

我在这个事务中进行的操作比如修改某条数据,在事务没有提交前,另一个事务中是查不到修改的
这是隔离性,注意区别

以上是关于对事务一致性的理解的主要内容,如果未能解决你的问题,请参考以下文章

谈一谈 对 事务 的理解

事务的理解

谈谈你对事务的理解,事务的特性

谈谈你对事务的理解,事务的特性

谈谈你对事务的理解,事务的特性

Spring相关面试题:谈一谈你对事务的理解?