事务的ACID概念

数据库中的事务就是一组原子行的SQL查询,或者说一个独立的工作但愿。也就是说,事务内的语句,要么全部执行成功,要么全部执行失败。

ACID表示原子性(atomicity)、一致性(consistency)、隔离行(isolation)和持久性(durability)。一个运行良好的事务处理系统,必须具备这些特征。

一个实现了ACID的数据库,相比于没有实现ACID的数据库,通常需要更强的CPU,更大的内存,更多的存储空间。所以对于一些不需要事务支持的查询类型应用,选择一个非事务型的存储引擎,是可以获得更高的性能的。

事务ACID的概念

  • A,automicity 原子性

    即,一个不可分割的最小单元。

  • C,consistency 一致性

    总是从一种状态到另一种状态,没有第三种状态。

  • I,isolation 隔离性

    一个事务再提交之前,对其他事务是不可见的。即不同的事务之间相互之间不影响。

  • D,durability 持久性

    事务一旦提交,就会永久生效。

隔离级别

隔离级别,规定一个事务中所做的修改,哪些是在事务内和事务间是可见的,哪些是不可见的。
一般,较低隔离级别的隔离可以支持更高的并发,系统的开销会更低。

隔离要解决的问题

  • 脏读,Dirty read

    即其他事务可以读取到当前事务未提交的数据。

  • 不可重复读,nonrepeatable read

    即两次执行同样的查询,得到的结果可能是不一样的。

  • 幻读,Phantom read

    某一个事务在取一范围记录时,另一事务又在该范围插入了新纪录,当之前事务再读取该范围是,就会产生幻读。

不同的隔离划分

隔离级别 脏读 不可重复读可能性 幻读 加锁读
read uncommitted Y Y Y Y
read committed N Y Y N
repeatable read N N Y N
serializable N N N Y
  • Read uncommitted(未提交读)

    在这个级别下,事务中的修改,即使在没有提交的情况下,其他的事务也是可见的。
    所以,除非有非常必要的理由,在实际应用中一般很少使用。

  • Read committed(提交读)

    read committed隔离级别满足前面提到的隔离性的定义。即一个事务开始时,只能看见已经提交的事务所做的修改。换句话说,一个事务从开始到提交之前,所做的任何修改对其他的事务都是不可见的。
    大多数的数据库系统的默认隔离级别都是这个级别
    但这个级别有时候会出现不可重复读的现象,即执行两次同样的查询可能会得到两个不同的结果。

  • repeatable read(可重复读)

    该级别解决了脏读的问题,而且保证了在同一个事务中多次读取同一条记录的结果是一致的。
    该级别是MySQL的默认事务级别
    但是理论上,该级别下会出现另一个幻读的问题。
    MySQL的InnoDB通过多版本并发控制(MVCC)来解决了该级别下出现幻读的可能性问题。

  • serializable(可串行化)

    该级别为最高的隔离级别。他通过强制事务串行执行,避免了前面 repeatable read 级别下可能会出现幻读的情况。简单说,就是serializable会在读取的每行数据上都加锁。所以会导致大量的超时和锁争用的情况。故实际应用中该级别也很少用到。