MySQL 事务

目录

事务就是一次原子性的 SQL 查询,在一次事务中的多个 SQL 查询,要么全部成功,要么全部不成功。

事务特性ACID

  • 原子性(atomicity):一个事务必须视作不可分割的最小单元,所有操作要么全部成功,要么全部失败。
  • 一致性(consistency):数据库总是从一个一致性的状态到另外一个一致性的状态,不会出现事务中的 SQL 部分成功导致数据不一致的情况。
  • 隔离性(isolation):通常来说一个事务所做的修改在提交之前对其他事务是不可见的,具体需要依隔离级别而定。
  • 持久性(durability):一旦事务提交,所做的修改就会永久保存到数据库中。

事务隔离级别

  • 未提交读(READ UNCOMMITTED):事务中的修改,即使没有提交,在别的事务中也是可见的,这也称为脏读(Dirty Read)

  • 提交读(READ COMMITTED):一个事务开始时,只能看到已提交的修改,满足隔离性的简单定义。也称为不可重复读(Nonrepeatable Read),因为在这个事务开始和结束后读取到的数据是不一样的。此级别是大部分数据库系统的默认隔离级别。

  • 可重复读(REPEATABLE READ):该级别保证了在一个事务中多次读取同样记录的结果是一致的,解决了脏读的问题,但是会出现幻读的问题。此级别是 MySQL 的默认隔离级别。MySQL InnoDB RR隔离级别不会出现幻读的情况: RR隔离级别保证对读取到的记录加锁 (记录锁),同时保证对读取的范围加锁,新的满足查询条件的记录不能够插入 (间隙锁)

  • 可串行化(SERIALIZABLE):这是最高的隔离级别,强制事务串行执行,避免幻读的可能,但是此隔离级别会在读取的每一行数据上都加锁,可能导致大量的超时和锁竞争的问题。

隔离级别 脏读 不可重复读 幻读 加锁读
READ UNCOMMITED Yes Yes Yes No
READ COMMITTED No Yes Yes No
REPEATEBLE READ No No Yes No
SERIALIZABLE No No No Yes

幻读和不可重复读的区别

  • 不可重复读:事务 A 两次查询结果不一致;事务 A 查询第一次,事务 B 修改查询数据并提交,事务 A 查询第二次,此时第二次数据和第一次数据不一致,这就是不可重复读。

  • 幻读:是不可重复读的一种特例;事务 A 通过范围查询第一次,事务 B 插入一条新数据在 A 的查询范围内,事务 A 第二次查询会发现,比第一次查询多一条数据,也就是出现了幻行的现象。