SQL 事务1

1. 定义

慕课解释: 事务(Transaction)是数据库中的一个核心概念,指的是将数据库的一组操作作为一个整体,要么全部执行,要么都不执行。

2. 前言

本小节,我们将一起学习数据库中的一个重点内容——事务

事务并非 SQL 中独有,在数据库、编程语言、各类框架中均有出现,而且无一例外都是重点。事务是一个较为复杂的概念,本小节会有一定的理论阐述,当然也会有一些小例子来帮助你理解。

事务的内容比较多,本小节会介绍事务的概念和基本使用,下一小节我们再来探讨事务的四种隔离级别。

本小节测试数据如下,请先在数据库中执行,本小节的所有操作若无特殊说明默认在 MySQL 中执行。

DROP TABLE IF EXISTS imooc_user;
CREATE TABLE imooc_user
(
  id int PRIMARY KEY,
  username varchar(20),
  age int
);
INSERT INTO imooc_user(id,username,age)
VALUES (1,'peter',18),(2,'pedro',24),(3,'jerry',22),(4,'mike',18),(5,'tom',20);

3. 理论

3.1 特性

事务具有四大特性,即ACID,它们分别是:

  • 原子性(Atomicity):每个事务都是一个整体,不可再拆分,事务中的 SQL 操作要么全部执行成功,要么全部失败。
  • 一致性(Consistency):事务执行前后数据库的状态必须保持一致。如 A 转账给 B,转账后金额的总数是不变的。
  • 隔离性(Isolation):事务与事务之间互不影响,彼此隔离。
  • 持久性(Durability):事务一旦提交成功,对数据库的更改就是永久的,即使出现了其它情况,数据改变仍然存在。

事务的四大特性是事务最本质的特点,在这四个特性中,原子性是基础,隔离性是手段,一致性是约束条件,而持久性是我们的目的。

3.2 语法

事务是一组操作的集合,因此没有固定的语法格式,事务常见的控制语句如下:

  1. START TRANSACTIONBEGIN,用来显式地开始一个事务。
  2. COMMIT,提交事务。
  3. SAVEPOINT,创建保存点,一个事务可以有多个保存点,事务可以根据保存点进行回滚。
  4. ROLLBACKROLLBACK TO [SAVEPOINT],回滚事务,默认回滚所有更改,如果加上保存点,则回滚到保存点。
  5. RELEASE SAVEPOINT,释放保存点,即删除某个保存点,保存点被删除后,不可回滚。
  6. SET TRANSACTION,设置事务的隔离级别,在下小节将会详细介绍。

提示: 并不是每个数据库引擎都支持事务,如 MySQL 的 MyISAM 引擎就不支持事务。

4. 实践

事务使用的一般流程为:通过 BEGIN 开始一个事务,进行一组数据操作,如果操作成功,通过 COMMIT 提交事务,否则通过 ROLLBACK 回滚。

4.1 例1 提交事务

请书写 SQL 语句,通过一个事务向imooc_user表插入一个用户,用户名为lucy,年龄为21,并提交事务。

分析:

先显示通过 BEGIN 开始一个事务,然后使用 INSERT 语句插入用户,再通过 COMMIT 提交事务即可。

语句:

整理可得语句如下:

BEGIN;
INSERT INTO imooc_user(id,username,age) VALUES (6,'lucy',21);
COMMIT;

执行成功后,结果如下:

+----+----------+-----+
| id | username | age |
+----+----------+-----+
| 6  | lucy     | 21  |
+----+----------+-----+

4.2 例2 回滚事务

事务提交和事务回滚是一对互斥操作,事务回滚后,事务之前的操作都将失效

请书写 SQL 语句,通过一个事务向imooc_user表插入一个用户,用户名为dell,年龄为21,并回滚事务。

分析:

先显示通过 BEGIN 开始一个事务,然后使用 INSERT 语句插入用户,再通过 ROLLBACK 回滚事务即可。

语句:

整理可得语句如下:

BEGIN;
INSERT INTO imooc_user(id,username,age) VALUES (7,'dell',21);
ROLLBACK;

执行成功后,dell 并未被插入到 imooc_user 表中,可见 ROLLBACK 的确撤销了之前的数据操作。

4.3 例3 回滚且提交事务

前面谈到,事务的回滚是可以指定保存点的,因此我们可以只回滚部分操作,提交其它操作。

如下:

BEGIN;
INSERT INTO imooc_user(id,username,age) VALUES (8,'stark', 20);
SAVEPOINT savepoint1;
INSERT INTO imooc_user(id,username,age) VALUES (9,'alice', 20);
ROLLBACK TO savepoint1;
COMMIT;

上面的 SQL 语句的大致执行流程如下:

  1. BEGIN 显示的开启了一个事务。
  2. 向 imooc_user 表中插入了用户 stark ,并且通过 SAVEPOINT 新建了保存点 savepoint1。
  3. 又向 imooc_user 中插入了另外一个用户 alice。
  4. 通过 ROLLBACK 将事务回滚到了 savepoint1,即第2个插入语句将会失效。
  5. 提交事务。

执行成功后,数据如下:

+----+----------+-----+
| id | username | age |
+----+----------+-----+
| 8  | stark    | 20  |
+----+----------+-----+

从结果中可以得出,alice 用户并没有插入成功,这与我们的分析一致,也验证了事务的强大。

5. 小结

  • 事务是数据库的重点,也是很多框架的重点,是支撑并发的基石,因此请务必多多练习事务的使用。
  • 事务的四大特性虽然内容较多,但历来都是面试的重点,请务必理解并且熟稔于心。