事务 ACID

Posted bibo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了事务 ACID相关的知识,希望对你有一定的参考价值。

事务是定义一系列操作在逻辑上可以看成一个完整的操作,具有ACID特性;

Atomicity(原子性)

  要求事务中所有的操作要么全部完成,要么全部没有发生,如果部分操作失败,则整个事务操作都会失败。

Consistency(一致性)

  要求事务中的操作,符合容器(如:数据库)的各种规则,保证数据是合法、与规定好的方式运行,一般通过原子性来保证,数据在事务中会有各种状态,但是结果必须需要语义。

  与原子性强调开始/结束状态不一样,一致性强调的是在事务过程中数据状态的不稳定,其他事务是不可见的。(隔离级别会有一些妥协)

Isolation(隔离性)

  事务与事务间不会相互影响,就像串行执行一样,相互之间并行时是不可见的。

Durability(持久性)

  事务完成后,数据状态就保持不变,永久存储。

目前大致有两种比较流行的技术来实现事务:预写日志(WAL)和影子分页(SP)

预写日志(write-ahead logging),主要提供ACID中的原子性和持久性两种特性的操作:

  日志分为redo和undo信息,

  undo用于记录修改前的信息,redo用于记录修改后的信息;undo可用于做事务失败的回滚操作,redo可用于做事务提交过程中故障恢复。log文件一般采用追加的方式,I/O效率高。

  WAL要求对数据的修改必须只能在这些修改已经记录了日志之后,那么就不需要每次事务提交的时候都实时刷新数据到磁盘。

  这种方式能使局部的顺序I/O(根据日志顺序地对各个区域进行I/O)取代全局的随机I/O(大量并发的I/O不是针对同一区域)。

  检查点  

    注意:一般日志文件非常大,在做恢复时如果顺序查找非常消耗时间,所以就设计了检查点来提高效率,数据恢复只需要从最近的检查点开始。

    一般的检查点称为静态检查点,在事务并发时需要夯住所有的事务(不然会有事务没有提交就设置了检查点,在恢复时就变成了脏数据),这种开销较大。

    所以就提出了非静态检查点,在不夯住事务的情况下,记录检查点的开始和结束,在开始点记录正在活跃的事务,在上一次活跃的事务结束后记录结束点。恢复时从结束点到开始点中查找未完成的事务,并丢弃这些数据,然后从结束点恢复数据。

影子分页(shadow pagging)

  在事务发生前,拷贝一份当前数据的数据页作为影子页存储在不易丢失的存储器中,

  提交事务时,保证主存中该事物的修改都刷新到磁盘上,并且不能覆盖影子页,然后使用当前页的磁盘地址写到影子页的地址,覆盖影子页地址,于是当前页就作为新的影子页。

  当发生故障需要恢复旧数据时,需要将影子页拷贝到主存,用它做后续事务处理。

影子分页相对于预写日志的方式的缺点:

  提交开销大,一个事务需要提交多个块信息(实际数据块、当前页表、当前页表的磁盘地址),而预写日志的方式只需要日志记录。

  数据分片,影子分页技术在数据更新时需要改变数据块页的存储位置。

  垃圾回收,影子分页在事务提交后,提交前的数据就编程垃圾数据,需要将垃圾页加入空闲页列表。

 

隔离性

  不同产品的实现不完全一样。

  比如mysql就提供了4中隔离级别:

  1、Read Uncommitted 其他的事务可以看到当前事务未提交的结果。

  2、Read Committed 只有当前事务已经提交后,其他事务才能看到结果。

  3、Repeatable Read (默认事务)  同一事务的不同实例读取的数据一致。(Innodb 使用MVCC, multiversion concurrency control)机制解决 

  4、Serializable 强制事务排序。

 

下一篇将记录  事务的一致性问题

以上是关于事务 ACID的主要内容,如果未能解决你的问题,请参考以下文章

事务的特性ACID

数据库事务——事务的特性(ACID)

数据库事务——事务的特性(ACID)

MySQL事务ACID特性

事务的ACID

Mysql事务隔离级别及ACID实现原理