一、概述
- 事务又叫做TCL,全称是transaction control language,意思是事务控制语言;
- 事务主要用于处理操作量大,复杂度高的数据,是保证数据一致性的重要手段;
- 在 MySQL 中只有使用了 Innodb数据库引擎的数据库或表才支持事务;
二、事务的4大特性
一般来说,事务是必须满足4个条件(ACID)
- 原子性(Atomicity,或称不可分割性):一个事务中的所有操作,要么全部完成,要么全部不完成,执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态;
- 一致性(Consistency):在事务开始之前和事务结束以后,数据库的完整性没有被破坏,多个用户的事务获取到的数据一致。这表示写入的资料必须完全符合所有的预设规则;
- 隔离性(Isolation,又称独立性):数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable);
- 持久性(Durability):事务处理结束后,对数据的修改就是永久的
三、事务的隔离级别
参考https://blog.csdn.net/qq_37651267/article/details/92425172
四、禁止和开启事务
在 MySQL 命令行的默认设置下,事务都是开启自动提交的,可以使用SET命令禁用和再开启
SET AUTOCOMMIT=0 -- 禁止自动提交
SET AUTOCOMMIT=1 -- 开启自动提交
五、事务控制语句
1、开启事务
BEGIN TRANSACTION 或 START TRANSACTION 或 SET AUTOCOMMIT=0
2、回滚
回滚会结束用户的事务,并撤销正在进行的所有未提交的修改
ROLLBACK 或 ROLLBACK WORK
3、创建一个保存点
在事务中创建一个保存点,一个事务中可以有多个 SAVEPOIN
SAVEPOINT identifier
4、删除一个保存点
RELEASE SAVEPOINT identifier
5、回滚到保存点
会撤销保存点后的操作
ROLLBACK TO identifier
6、设置事务的隔离级别
SET TRANSACTION -- 隔离级别 READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ 和 SERIALIZABLE
六、测试示例
mysql> use spring;
Database changed
mysql> show tables;
+------------------+
| Tables_in_spring |
+------------------+
| job |
| salaryview |
| testtab |
| userinfo |
+------------------+
4 rows in set (0.12 sec)
mysql> select * from testtab
-> ;
+----+-------+
| id | name |
+----+-------+
| 1 | agale |
+----+-------+
1 row in set (0.02 sec)
mysql> begin; # 开启事务
Query OK, 0 rows affected (0.01 sec)
mysql> insert into testtab(name) values('ken');
Query OK, 1 row affected (0.01 sec)
mysql> select * from testtab; # 在该事务中未提交的数据也能查到
+----+-------+
| id | name |
+----+-------+
| 1 | agale |
| 2 | ken |
+----+-------+
2 rows in set (0.04 sec)
mysql> rollback; # 回滚未提交的操作
Query OK, 0 rows affected (0.07 sec)
mysql> select * from testtab;
+----+-------+
| id | name |
+----+-------+
| 1 | agale |
+----+-------+
1 row in set (0.03 sec)
mysql> commit;
Query OK, 0 rows affected (0.01 sec)
mysql> select * from testtab;
+----+-------+
| id | name |
+----+-------+
| 1 | agale |
+----+-------+
1 row in set (0.04 sec)
mysql> begin;
Query OK, 0 rows affected (0.01 sec)
mysql> update testtab set name = 'jerry' where id =1;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from testtab;
+----+-------+
| id | name |
+----+-------+
| 1 | jerry |
+----+-------+
1 row in set (0.03 sec)
mysql> savepoint kk; -- 在更新id = 1的数据后创建一个保存点
Query OK, 0 rows affected (0.01 sec)
mysql> insert into testtab(name) values('tom');
Query OK, 1 row affected (0.01 sec)
mysql> select * from testtab;
+----+-------+
| id | name |
+----+-------+
| 1 | jerry |
| 3 | tom |
+----+-------+
2 rows in set (0.04 sec)
mysql> rollback to kk; -- 回滚到保存点,只会撤销刚才的insert
Query OK, 0 rows affected (0.01 sec)
mysql> commit;
Query OK, 0 rows affected (0.06 sec)
mysql> select * from testtab;
+----+-------+
| id | name |
+----+-------+
| 1 | jerry |
+----+-------+
1 row in set (0.04 sec)
mysql>