导言 您的程序总是打开交易。
注册会写出新的用户行 。
退票借记一个账户并贷记另一个账户。
提交的表格同时更新了三个相关的表格。
你用BEGIN和COMMIT 来包装,然后继续, 相信数据库会处理 任何发生在两者之间的事情。
大多数时候都是这样 但当它处理这件事时 它能给你带来什么?
为了兑现诺言 它在幕后做什么?
说一个用户从A账户转入B账户 $ 1000。
应用程序运行两个更新:从 A 中减去 1000, 在 B 中添加 1000 。
现在说服务器在第一次更新运行之后但第二次更新运行之前崩溃 。
账户A: - -- -- -- -- -- 1 000账户B: -- -- -- -- 那笔钱没动过 它不见了。
没有错误消息可以校正,也没有用户接受"服务器重启"作为其缺失余额的解释.
这就是所谓的ACID的一套保证 是为了解决的 大多数开发者可以背出缩写"原子","一致性","孤立","被毁灭"等词语,而没有能够解释四个单词中任何一个字实际承诺的内容,或者数据库内部必须做什么来兑现这些承诺.
这篇文章试图解决这个问题。
1.
什么是交易?
在ACID讲得通之前,你需要了解实际交易是什么.
交易是一组一个或多个数据库操作,作为单一的逻辑工作单位处理.
要么整个团体都成功,要么没有成功。
上面的银行转账是一种教科书交易:两个更新只合情合理.
在SQL中,一个交易通常看起来是这样:BEGIN告诉数据库"从这里开始的一切都是一个单位".
COMMIT告诉它"我们结束了,让它永久化".
如果在两者之间发生出错, 违反约束, 崩溃, 决定取消的应用程序, 数据库可以发布一个 ROLLBACK , 取消迄今为止所做的任何更改 。
从外而外,似交易从来不跑.
这个单一的想法,一个交易要么完全发生要么完全不发生,就是ACID的种子从中长出. - 说吧
2.
原子性:所有或无原子性是保证将交易的业务视为一个不可分割的单位。
如果任何部分失败,交易本身的效果会回滚,因此不会留下部分结果.
这就是防止"钱失踪"情景发生的原因.
如果第二个 UPDATE 从未运行过,数据库也会卷回第一个,因此A账户在用户或另一交易可以观察到的任何状态中都不会真正失去它的资金.
精确地说,原子学能做什么,不能涵盖什么 它保证整个交易是全或全无的。
这并不意味着每个单个的语句在每一个数据库引擎中都表现得相同,它没有说其他同时进行的交易在运行时可以看到什么.
这是一个不同的保证, 这是有趣的一个。 --
3.
一致性:保留数据库规则 这是人们最常犯错的词,通常通过将其简化为"数据库有正确的数据".
这太模糊了,没有用处。
在ACID中,一致性是指一个成功的交易将数据库从一个有效的状态带到另一个有效的状态,其中"有效"是由你让数据库执行的限制和规则定义的.
一致性并不是数据库神奇地猜测的东西。
您定义它: 一个 CHECK 的制约, 表示平衡不能去负数 外国密钥, 需要命令的客户 id 引用客户表格中的实际行 UNIQUE 的制约, 表示两个用户不能共享相同的电子邮件地址 。
如果一项交易违反其中任何一项,则数据库拒绝执行,而是将其卷回。
一致性其实是执行你规则的数据库,而不是独立决定正确内容的数据库.
也值得将ACID一致性与一个完全不同的想法区分开来,这个想法和同一个词是:distribu的一致性