浅谈数据库事物

1 银行的那些事

银行应用是解释事务必要性的一个经典例子。假设一家银行的数据库有两张表:支票(checking)表和储蓄(savings)表。现在客户葫芦爷爷要从支票账户转移200美元到储蓄账户,那么需要至少三步:

  1. 检查支票账户的余额高于200美元。
  2. 从支票账户余额中减去200美元。
  3. 从储蓄账户的余额中增加200美元。

上述三个步骤必须打包在一个事务当中,任何一个步骤失败,则必须所有步骤全部失败回滚。

第一步-- start transaction;
第二步-- select balance from checking where customer_id=1022376;
第三步-- update checking set balance=balance-200.00 where customer_id=1022376;
第四步-- update savings set blance=balance+200.00 where customer_id=1022376;
第五步-- commit  /  rollback ;

单纯的事务并不是故事的全部。设想一下;如果执行到第四步操作时服务器崩溃了,会发生什么?天知道用户可能会损失200美元。

除非系统通过严格的ACID测试。ACID 即包含:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability);指数据库事务正确执行的四个基本要素;

2 ACID

原子性(atomicity)

一个事务必须被视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚,对于一个事务来说,不可能只执行其中的一部分操作,这就是事务的原子性。

一致性(consistency)

数据库总是从一个一致性的状态转换到另一个一致性的状态。在前面的例子当中,一致性确保了即使在执行第三四条语句时系统崩溃,支票账户也不会损失200 美元,

隔离性(isolation)

通常来说,一个事务所做的修改在最终提交之前,对其他事务是不可见的。在前面的例子当中,当执行完第三条语句,而第四条语句还未执行时,此时另外一个账户汇总程序开始运行,则看到支票账户的余额并没有减去200美元。

持久性(durability)

一旦事务提交则其所做的改变就会永久的保存到数据库中,以供下一次增删改查操作。

3 但是

事务的ACID特性可以确保银行不会弄丢葫芦爷爷的钱。而在应用逻辑中,要实现这一点非常难,甚至可以说是不可能完成的任务,一个兼容ACID的系统,需要做很多复杂但可能用户并没有察觉的操作,才能确保ACID的实现。

这就像锁粒度一样,会增加系统开销,这种事务处理过程中的额外的安全性,也需要数据库系统做更多的额外工作。


4 事务隔离

https://baijiahao.baidu.com/s?id=1611918898724887602&wfr=spider&for=pc

4.1 一般的数据库,都包括以下四种隔离级别:

  1. 读未提交(Read Uncommitted):可以读到未提交的内容
  2. 读提交(Read Committed):只能读到已经提交了的内容(大部分)
  3. 可重复读(Repeated Read):MySql的默认隔离级别;专门针对“不可重复读”这种情况而制定的隔离级别
  4. 串行化(Serializable):数据库最高的隔离级别;就是事务一个一个排队执行

4.2 数据错误

  1. 脏读---(读取事务未提交数据)
  2. 不可重复读---(前后多次读取,数据内容不一致)
  3. 幻读---(前后多次读取,数据总量不一致)

4.3 关系表

隔离级别 脏读(Dirty Read) 不可重复读(NonRepeatable Read) 幻读(Phantom Read)
读未提交(Read uncommitted) 可能 可能 可能
读已提交(Read committed) 不可能 可能 可能
可重复读(Repeatable read) 不可能 不可能 可能
可串行化(Serializable ) 不可能 不可能 不可能
posted @ 2019-07-05 19:09  du-z  阅读(284)  评论(0)    收藏  举报