2

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(读未提交):

image.png

  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(读已提交):

image.png

  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(串行化):

image.png

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

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

读现象

脏读

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

不可重复读

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

幻影读

在一次事务中,查询多次的结果集不是一致的。
image.png

  1. 事务2查询id在1到10直接的名称,假设有5个
  2. 事务1插入id为9的数据
  3. 事务1提交
  4. 事务2查询id在1到10直接的名称,此时有6个
隔离级别和读现象的关系

image.png

持久性

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


大军
847 声望183 粉丝

学而不思则罔,思而不学则殆


下一篇 »
浅谈CAP定理