数据库事务 - 它们如何工作?

fle*_*her 33 database transactions

我正在尝试更多地了解数据库事务,我发现ACID用于编写事务的经验法则和几个问题的思考.

ACID经验法则:

交易必须是:

  1. 原子 - 它是一个工作单元,不依赖于以前和以后的交易.
  2. 一致 - 数据被提交或回滚,没有"中间"的情况,其中某些东西已经更新,而某些东西没有.
  3. 隔离 - 没有事务看到当前事务的中间结果.
  4. 持久 - 即使系统在之后崩溃,如果数据已提交,则值仍然存在.

我想知道它们是如何工作的,所以我可以更好地理解在编写这样的交易时需要考虑的因素.我想具体细节会因可用的数据库实现而有所不同,但某些规则将始终存在.

  1. 数据库如何处理并发事务,同时仍支持Atomic规则?
    • 是否有按顺序处理的事务队列?
    • 如何处理阻碍所有其他交易的冗长交易?
  2. 是否在内存中完成了对表的更新,因此如果在提交之前发生了崩溃,那么数据库是否没有更改?
    • 或者是否有一些中间表被更新以在这样的崩溃中幸存?
  3. 在事务正在进行的同时,是否阻止了对受影响表的所有读写访问?
    • 或者数据库是否允许写入,但事务会在提交时覆盖所有更改?

fre*_*ley 13

  1. 有许多不同的方式,包括事务排队,乐观并发控制等.这实际上是一个非常复杂的问题,有关于它的书籍:

    http://www.amazon.co.uk/Databases-Transaction-Processing-Application-Oriented-Approach/dp/0201708728/ref=sr_1_3?ie=UTF8&s=books&qid=1281609705&sr=8-3

  2. 它取决于数据库中的日志记录级别.如果保留严格的预写日志,则在系统崩溃的情况下,数据库可以回送到一致状态.

  3. 这取决于并发的类型.乐观并发不涉及锁定,但如果事务完成后db的状态已更改,则会放弃并重新启动它.这可以加速碰撞很少的dbs.还有不同级别的锁定:行,表,甚至整个数据库.

这些都是非常复杂的问题,如果你想完全回答这些问题,我建议买一本书,或参加并发系统讲座系列:-)

  • 啊。书籍推荐作为答案本身。不,谢谢,投反对票。如果你想参考一本书,那很好,但要给出一个实际的答案,即使它更抽象。 (3认同)
  • 此外,我发现一般而言,书籍推荐是另一种说法,即“我手头并没有完全理解来回答您的问题”,这与 SO 的答案应该是相反的。 (3认同)

Erw*_*out 10

您定义的一些挑剔:

原子 - 它是一个工作单元,不依赖于以前和以后的交易.

更正确的原子性定义不会提及任何"之前或之后"的交易.原子性是单个事务本身所具有的属性,即在最终倒计时中,要么所有操作都持续存在,要么根本不存在.换句话说,不应该允许"只有一半的交易"持续存在.

但是,这个概念被诸如嵌套事务,保存点以及用户请求显式回滚直到采用的保存点的概念所模糊.从某种意义上说,这些确实允许"只有事务的一半动作"持续存在,尽管是在明确的用户请求下.

一致 - 数据被提交或回滚,没有"中间"的情况,其中某些东西已经更新,而某些东西没有.

这种解释是完全错误的.一致意味着事务处理器(在这种情况下,DBMS引擎)不能使系统(数据库)处于违反它(事务处理器)知道的任何声明的约束的状态.例如,参见Chpt 16的"数据库系统简介".

隔离 - 没有事务看到当前事务的中间结果.

挑剔:除了当前的交易之外,没有任何交易可以看到中间状态(状态,而不是真正的结果).请注意,事务处理引擎的"隔离级别"通常定义可以违反I属性的程度!

持久 - 即使系统在之后崩溃,如果数据已提交,则值仍然存在.

但是这个属性也因嵌套事务的可能性而有些模糊.即使内部事务已提交并完成,包含事务仍然可以通过自身完全回滚来撤消该提交.


Han*_*son 6

实际细节可能在某种程度上取决于它是哪个DB服务器,但您可能会对此文章感兴趣:事务处理备忘单

  • 该链接不再可用,但 Wayback Machine 保留了一份副本(不含图像):http://web.archive.org/web/20120827100207/http://www.cbare.org/writing/Transactions/transactions。 html (2认同)