跳到主要内容

数据库事务

https://zhuanlan.zhihu.com/p/87627212

https://www.zhihu.com/question/31346392

https://zhuanlan.zhihu.com/p/29166694

『MySQL』深入理解事务的来龙去脉 - 掘金

Innodb中的事务隔离级别和锁的关系 - 美团技术团队

MySQL 中的事务主要用于执行多个数据库的操作,保证每一条操作都执行成功,否则就全部操作进行回滚。

在 MySQL 命令行的默认设置下,事务都是自动提交的,即执行 SQL 语句后就会马上执行 COMMIT 操作。因此要显式地开启一个事务务须使用命令 BEGIN 或 START TRANSACTION,或者执行命令 SET AUTOCOMMIT=0,用来禁止使用当前会话的自动提交。

ACID 特性

为了保证事务的正确执行,事务都应具备原子性、一致性、隔离性与持久性这四个特性,简称为 ACID。

  • 原子性(Atomicity):对于事务来讲,原子性代表着事务中包含的所有操作都是不可再拆分的,并且视为一个整体。在事务执行时,要么所有操作执行成功,否则全部失败,不会结束在中间某个环节,若中间某个执行过程发生错误,那么系统会被回滚到事务开始前的状态。
  • 一致性(Consistency):在事务执行前后,数据库的都具有正确的状态,即写入的所有资料都是符合预设条件的。简单来讲,事务操作会使系统从一个正确的状态,迁移到另一个正确的状态。需要注意的是,一致性的前置条件即是需要满足中其余三个特性。
  • 隔离性(Isolation):多个事务间是相互隔离的,互不影响,数据库允许多个并发事务同时对数据进行读写,而隔离性可以防止多个事务间由于交叉执行而导致数据不一致的问题。简单来讲,一个事务所做的修改在最终提交以前,对另一个事务都是不可见的。
  • 持久性(Durability):事务的处理结果能够被储存下来,即使系统崩溃后,修改的数据也不会丢失。

脏读、不可重复读与幻读

脏读

脏读是指一个事务访问到了另一个事务未提交的修改。

不可重复读

事务对同一个数据查询多次,但在读取的过程中有其他事务对该数据进行了修改或者删除,导致两次查询结果不一致,从而导致的操作问题称之为不可重复读。

幻读

幻读,并不是说两次读取获取的结果集不同,幻读侧重的方面是某一次的 select 操作得到的结果所表征的数据状态无法支撑后续的业务操作。举一个例子,当我们 select 一个数据不存在时,执行 insert 却发现数据已经存在了,这时操作会失败,说起来就如同幻觉般。

隔离级别

数据的隔离级别有 4 种,从低到高分别为:读未提交、读已提交、可重复读以及可串行化,级别越高,数据越安全,性能开销也越大,使用不同的隔离级别,我们可以应对脏读、不可重复读、幻读等系列问题:

读未提交(Read Uncommitted)

读已提交(Read Committed)

可重复读(Repeatable Read)

可串行化(Serializable)

悲观锁和乐观锁