1、概念

  • 事务是最小的,不可分割的工作单元,一个事务对应一个完整的业务流程,比如转账操作。
  • 数据库系统引入事务的目的是:事务会把数据库从一种一致性状态转换为另一种一致性状态。

2、特性

概念来自:MySQL 事务

  • 原子性(atomicity)/ˌætəˈmɪsəti/
    一个事务中的所有操走,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚到事务开始前的状态,就像这个事务从来没有执行过一样。
    事务的原子性通过redo log实现。
  • 一致性(consistency)/kənˈsɪstənsi/
    在事务开始之前和事务结束之后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
    事务的一致性通过undo log实现。
  • 隔离性(isolation)/ˌaɪsəˈleɪʃn/
    数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个并发事务执行时由于交叉执行而导致数据的不一致。
    事务的隔离性通过锁来实现。
  • 持久性(durability)/ˌdʊrəˈbɪləti/
    事务处理结束后,对数据的修改是永久的,即使系统故障,数据也不会丢失。
    事务的持久性通过redo log实现。

3、InnoDB中的事务隔离级别

  • 读未提交(Read Uncommited)
    事务A未提交的数据,事务B也可以读取到,会导致脏读、不可重复读、幻读。
  • 读已提交(Read Commited)
    允许读取并发事务已经提交的数据,但是会有不可重复读、幻读现象。
  • 可重复读(Read Repeatable)
    对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改。除了会对读取的记录加锁,还会在记录之间加上间隙锁,不存在幻读现象。
  • 串行化(Serializable)
    从MVCC并发控制退化到基于锁的并发控制,读写冲突,并发降低。

MySQL的默认事务隔级别是Read Repeatable,因为InnoDB采用Next-Key Lock解决了幻读,所以这个隔离级别符合ACID的要求。

4、MVCC

来自:何登成的技术博客
多版本并发控制协议,读不加锁,读写不冲突。
在MVCC并发控制中,读可以分为两种:

4.1、快照读(Snapshot Read)

读取的是记录的可见版本,也可能是历史版本,不加锁。
简单的读取操作属于快照读,如:

1
select * from t where ?;

4.2、当前读(Current Read)

读取的是当前版本,当前读返回的记录都会加锁,防止其他事务修改。
特殊的读操作,插入/更新/删除操作,如:

1
2
3
4
5
select * from t where ? lock in share mode;  
select * from t where ? for update;
insert into t values(...);
update t set ? where ?;
delete from t where ?;

第一条加共享锁,其他都是排他锁。

在InnoDB存储引擎中,MVCC是通过Undo Log实现的。当读取一行记录时,若该记录已经被其他事务占用,当前事务可以通过Undo Log读取之前的行版本信息,以此实现非锁定读。

tencent.jpg