我正在尝试了解有关数据库事务的更多信息,我发现ACID用于编写事务的经验法则并考虑了几个问题。
ACID经验法则:
交易必须是:
- 原子 - 它是一个单位的工作,不依赖于以前和 以下交易。
- 一致 - 数据已提交或回滚,否 事物之间的“中间”案例 已更新但有些事情没有。
- 隔离 - 没有事务看到当前的中间结果 事务。
- 持久 - 即使数据已提交,值仍然存在 系统崩溃后立即崩溃。
醇>
我想知道它们是如何工作的,所以我可以更好地理解在编写这样的交易时需要考虑的因素。我想具体细节会因可用的数据库实现而有所不同,但某些规则将始终存在。
答案 0 :(得分:14)
有许多不同的方法,包括事务排队,乐观并发控制等。这实际上是一个非常复杂的问题,有关于它的书籍:
这取决于数据库中的日志记录级别。如果保留严格的预写日志,那么在系统崩溃的情况下,数据库可以恢复到一致的状态。
这取决于并发的类型。乐观并发不涉及锁定,但如果事务完成后db的状态已更改,则会放弃并重新启动它。这可以加速碰撞很少的dbs。还有不同级别的锁定:行,表,甚至整个数据库。
这些是非常复杂的问题,如果您希望能够完全回答这些问题,我建议您购买一本书或参加并发系统讲座系列: - )
答案 1 :(得分:11)
对你定义的一些挑剔:
Atomic - 它是一个工作单元,不依赖于之前和之后的交易。
更正确的原子性定义不会提及任何“之前或之后”的交易。原子性是单个事务本身所具有的属性,即在最终倒计时中,要么所有操作都持续存在,要么根本不存在。换句话说,不应该允许“只有一半的交易”持续存在。
然而,这个概念被诸如嵌套事务,保存点以及用户请求显式回滚直到采用的保存点的概念所模糊。从某种意义上说,这些确实允许“只有交易的一半动作”持续存在,尽管是在明确的用户请求下。一致 - 数据已提交或回滚,没有“中间”情况,其中某些内容已更新,而某些内容尚未更新。
这种解释是完全错误的。一致意味着事务处理器(在这种情况下,DBMS引擎)不能使系统(数据库)处于违反它(事务处理器)知道的任何声明的约束的状态。例如,参见“数据库系统简介”,第16章。
隔离 - 没有事务看到当前事务的中间结果。
挑剔:除了当前的之外,没有任何事务可以看到中间状态(状态,而不是真正的结果)。请注意,事务处理引擎的“隔离级别”通常会定义可以违反I属性的程度!
持久 - 即使系统崩溃,如果数据已提交,则值仍然存在。
但是这个属性也因嵌套事务的可能性而有些模糊。即使内部事务已提交并完成,包含事务仍然可以通过自身完全回滚来撤消该提交。
答案 2 :(得分:6)
实际细节可能在某种程度上取决于它是哪个数据库服务器,但您可能会对此文章感兴趣:Transaction Processing Cheat Sheet
答案 3 :(得分:3)
在实施方面,保证每个 ACID 属性都存在不平衡的努力。我可以在简化的想法中总结一下:
tomicity最终依赖于锁定或其他原子操作来交换在事务中修改的数据(在 I solation中创建)与共享视图中的原始数据。 / p>
数据库如何处理并发事务,同时仍支持Atomic规则?
请参阅我 solation。
C 一致性依赖于更基本的 A tomicity和 I solation属性,并且更多地扩展到应用程序层而不是本质上属于数据库服务。
通过在修改后的数据上执行规则,确保规则(当 A tomicity和 I solation到位时)非常简单。
这可能引发哲学辩论。但在我看来,在其非常重要的情况下,在最终提交之前验证相关数据中的所有条件可以完全在应用程序逻辑中实现,也可以在数据库层中的特定于应用程序的过程中实现,这不会使它们成为特定于数据库的。数据库服务必须确保的最低限度是能够无错误地读取先前写入的数据。
是否在内存中完成了对表的更新,因此如果在提交之前发生了崩溃,那么数据库是否没有更改?
请参阅我分离。
请注意 ACID 中的 C 依赖性纯粹是逻辑的,静态的,并且没有与 CAP theorem <后面建议的数据传播相关的级别或等级/强>
我通过首先修改原始数据的副本(在将更改提交到共享视图之前)来普遍实现分离。
在事务正在进行的同时,是否阻止了对受影响表的读写访问权限?
通常,如果在一个事务中仅修改了数据副本,则其他事务通常不会看到这些更改。但是,隔离级别可能不同。
这是唯一的 ACID 属性,允许有一些级别和度数而不是简单的黑白。
最终,我分离是其实施中最深入的,并且可能在所有 ACID 属性之间进行权衡。关于此属性的 going in details 是关于数据库服务保证的第一个最重要的主题(即使在 CAP theorem 的上下文中,权衡再次围绕一致性进行权衡分布式数据的孤立视图)。
D 可用性实际上是 SLA 。
通常在正常的交易逻辑之外协商什么样的持久性(“写入可破坏的磁盘”或“在钚驱动的服务器的RAM中冗余分布”)。
实施也相当简单,只有在刷新所有可能的缓冲区后才能确认成功的事务。
两个对性能至关重要的实施方面( ACID 没有明确关心):
冲突检测
应该有一种方法(有效地)检测在另一个事务中同时执行的冲突更改。
一个极端的方面是锁定所有不需要冲突检测的东西(没有可能的并发)。
另一个极端点是乐观并发(至少部分)。然后需要知道是否存在并发更改。这可以通过运行计数器(版本号)或数据库中每个对象的校验和来实现。然后,这与 I solation的实施密切相关。
回滚程序
这需要维护原始值及其修改后的副本(事务日志)的数据结构以撤消更改。同样,这与如何实施 I 分离非常相关。
一些额外的简短信息:
答案 4 :(得分:1)
一致 - 数据已提交 或回滚,没有“中间”的情况 什么东西已经更新和 事情没有。
我不同意Erwin Smout关于Consistent意味着什么的观点 - 你的解释更接近金钱。根据我对Ramakrishnan and Gehrke的解释,一致状态超出了系统声明的约束。
如果通过借记一个帐户并贷记另一个帐户在两个帐户之间转帐,系统可能处于以下几个州:
在所有四个州中,系统的完整性约束都可以保持。但是第二个和第三个与系统的合理观点不匹配 - 钱应该在某个地方。所以这些不是一致的状态,而初始状态和最终状态是一致的。
事务不会自动使系统保持一致 - 它们使用户能够将其编写为一致。写得不好的交易可能会有一个忘记归功于第二个帐户的错误。事务运行良好,完整性约束将成立。
但正确编写的过程会使系统处于一致状态,进行一些暂时不一致的更改(例如,不在任何一个帐户中的钱),然后使系统恢复到一致状态。通过将这些步骤放在事务中,可以保证系统达到最终一致状态(提交时)或返回其初始一致状态(如果它回滚)。无论哪种方式,都保持一致性。
答案 5 :(得分:0)
“嵌套交易的判决是什么”
没有判决。存在嵌套事务。存在ACID属性。他们被迫共存。没有绝对的。当然不是ACID。