引言

写这篇文章是将数据库的事务是什么,事务的特性是什么(ACID),事务的并发会引起什么问题(脏读、不可重复读、幻读),怎么解决这个问题(事务的隔离级别)这几个知识点给串起来
引用文章:

事务是什么

事务是访问并可能更新各种数据项的一个程序执行单元

我们要求数据库系统维护事务的以下性质:

ACID:

  • 原子性(Atomicity)
    原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
  • 一致性(Consistency)
    事务前后数据的完整性必须保持一致。
  • 隔离性(Isolation)
    事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
  • 持久性(Durability)
    持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响

为什么要引入隔离级别和并发问题

如果只是单个事务的话,或者事务严格按顺序进行执行的话,保证ACID是不困难的,但是通常情况下,我们为了提高效率,希望在同一时间内,数据库系统可以进行多个事务,也就是并发。但是并发通常会导致数据的一致性受到影响。也就是,我们会因为并发而采取较弱级别的一致性规则。这个一致性规则,就被称为“隔离级别”,而在采用这些隔离级别通常会带来一些一致性受到损害的问题,我们给这些问题划分为脏读、 不可重复读、幻读

接下来首先介绍弱一致性可能会带来什么问题

并发问题

  • 脏读:一个事务读取了另一个事务未提交的数据;
  • 不可重复读:不可重复读的重点是修改,同样条件下两次读取结果不同,也就是说,被读取的数据可以被其它事务修改;
  • 幻读:幻读的重点在于新增或者删除,同样条件下两次读出来的记录数不一样。

小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表

接下来介绍不同的隔离级别会带来什么并发问题,以及可以解决什么并发问题

隔离级别

SQL规定的隔离级别如下:

  • READ UNCOMMITTED(未提交读):最低级别的隔离,通常又称为dirty read,它允许一个事务读取另一个事务还没commit的数据,这样可能会提高性能,但是会导致脏读问题;

  • READ COMMITTED(已提交读):在一个事务中只允许对其它事务已经commit的记录可见,该隔离级别不能避免不可重复读问题;

  • REPEATABLE READ(可重复读):在一个事务开始后,其他事务对数据库的修改在本事务中不可见,直到本事务commit或rollback。但是,其他事务的insert/delete操作对该事务是可见的,也就是说,该隔离级别并不能避免幻读问题。在一个事务中重复select的结果一样,除非本事务中update数据库。

  • SERIALIZABLE(串行化):最高级别的隔离,只允许事务串行执行。

    MySQL默认的隔离级别是REPEATABLE READ。
    图片说明