浅谈ACID

ACID

当我们学习数据库事务的时候,我们就知道了事务有4个特性,分别是原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。

原子性

要么全部成功,要么全部失败,只要有一个失败,已经成功的都要回滚。
比如A账号给B账号转账100块钱,正常情况是A扣款100块,然后B账号增加100块。如果A这边扣款成功,B增加100块的时候失败了,这个时候,A扣款的操作就要回滚,也就是A也不扣款,B也没新增。

一致性

wikipedia包含这类描述

Any data written to the database must be valid according to all defined rules, including constraints, cascades, triggers, and any combination thereof.

数据的写入,必须符合我们的定义的规则。比如我们定义了金额是数值型,那么久不能传入字符串。我们定义了金额不能小于0,那就不能赋值为负数(这个是我们程序定义的)。

隔离性

指并发中的事务,即便操作共同的数据时,每个是事务是相互隔离的,相互不能影响的,每个事务都有自己完整的事务空间。
隔离级别从低到高:

Read Uncommitted(读未提交):

浅谈ACID_第1张图片

  1. 事务1更新id为1的name为张三
  2. 事务2读取id为1的name,此时读取的值为张三
  3. 事务1更新id为1的name为李四
  4. 事务2读取id为1的name,此时读取的值为李四

在事务1还没提交的时候,事务2可以读取到事务1更改的值。

Read Committed(读已提交):

浅谈ACID_第2张图片

  1. 事务2读取id为1的name,假设读取的初始值为李四
  2. 事务1更新id为1的name为张三
  3. 事务2读取id为1的name,读取值为李四(这个跟上面不一样,此时事务1还没提交,是看不到修改后的值)
  4. 事务1提交
  5. 事务2读取id为1的name,此时读取的值为张三

上面例子可以看出,在同一个事务中,事务2读取的值是不一样的。

Repeated Read(重复读):

图跟上面一样

  1. 事务2读取id为1的name,假设读取的初始值为李四
  2. 事务1更新id为1的name为张三
  3. 事务2读取id为1的name,读取值为李四(这个跟上面不一样,此时事务1还没提交,是看不到修改后的值)
  4. 事务1提交
  5. 事务2读取id为1的name,此时读取的值为李四(这个与上面不一样的地方)

Serialization(串行化):

浅谈ACID_第3张图片

  1. 事务2读取id为1的name,假设读取的初始值为李四
  2. 事务1更新id为1的name为张三,被阻塞了,等user表的id为1的事务提交,这个时候,id为1的这行被锁住了。
  3. 事务2执行范围的查询语句
  4. 事务1修改或插入数据,都被阻塞,这个时候,user表都锁住了。

串行化,就是所有的事务串行的执行,一个事务执行才,才能执行后面一个。

读现象

脏读

当一个事务读取到另一个事务未提交的数据,就可能发生脏读。
参见读未提交的例子。

不可重复读

在一次事务中,查询多次的结果不是一致的,这表明发生不可重复读。
参见读已提交的例子。

幻影读

在一次事务中,查询多次的结果集不是一致的。
浅谈ACID_第4张图片

  1. 事务2查询id在1到10直接的名称,假设有5个
  2. 事务1插入id为9的数据
  3. 事务1提交
  4. 事务2查询id在1到10直接的名称,此时有6个

隔离级别和读现象的关系

浅谈ACID_第5张图片

持久性

指事务一旦提交,就永久保留下来。系统崩溃、机器宕机,只要重启数据库,就可以读取到数据。

你可能感兴趣的:(分布式)