事务是由一组SQL语句组成的逻辑处理单元,要么全部执行成功,要么全部执行不成功,例如银行汇款。Mysql中只有innodb和bdb类型(数据库引擎)的数据库才能支持事务处理。
事务处理可以确保非事务性单元的多个操作都能够完成,否则不会更新数据资源。
(1).事务的特性
1.原子性(atomicity)。一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
2.一致性(consistency)。在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
3.隔离性(isolation)。数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
4.持久性(durability)。持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。
这四个特性简称ACID。
(2).事务的实现
创建实验环境
mysql> create database test_db;
Query OK, 1 row affected (0.00 sec)
mysql> use test_db;
Database changed
mysql> create table user_tb(id int,name varchar(20));
Query OK, 0 rows affected (0.03 sec)
事务相关命令
set autocommit = {0|1}; 设置事务是否自动提交,0是禁止自动提交,1是开启自动提交。默认是自动提交。
begin; 开始事务。
start transaction; 开始事务,与begin;的作用一样。
savepoint [节点名称]; 设置一个节点,可以配合rollback使用。一个事务可以有多个节点。
rollback [to 节点名]; 返回到指定节点,如果不指定节点则返回上一个节点,最多返回到开始节点。
commit; 提交当前事务
在开始事务到提交事务或返回节点之间存在的SQL语句都是事务的一部分。但返回节点并不能结束事务。
事务的使用实例
mysql> begin; //开始一个事务
Query OK, 0 rows affected (0.00 sec)
mysql> insert into user_tb values(1,'张三');
Query OK, 1 row affected (0.00 sec)
mysql> select * from user_tb;
+------+--------+
| id | name |
+------+--------+
| 1 | 张三 |
+------+--------+
1 row in set (0.00 sec)
mysql> savepoint point1; //设置一个节点
Query OK, 0 rows affected (0.00 sec)
mysql> insert into user_tb values(2,'李四');
Query OK, 1 row affected (0.00 sec)
mysql> select * from user_tb;
+------+--------+
| id | name |
+------+--------+
| 1 | 张三 |
| 2 | 李四 |
+------+--------+
2 rows in set (0.00 sec)
mysql> rollback to point1; //回滚到节点point1
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user_tb; //可以看到数据回到节点point1时了
+------+--------+
| id | name |
+------+--------+
| 1 | 张三 |
+------+--------+
1 row in set (0.00 sec)
mysql> rollback; //回滚到开始节点
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user_tb; //查看是没有任何数据了
Empty set (0.00 sec)
mysql> rollback to point1; //再次尝试回滚到节点point1失败,说明point1节点已经被删除
ERROR 1305 (42000): SAVEPOINT point1 does not exist
mysql> insert into user_tb values(1,'王五');
Query OK, 1 row affected (0.00 sec)
mysql> select * from user_tb;
+------+--------+
| id | name |
+------+--------+
| 1 | 王五 |
+------+--------+
1 row in set (0.00 sec)
mysql> savepoint point1;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into user_tb values(2,'赵六');
Query OK, 1 row affected (0.00 sec)
mysql> commit; //提交当前事务
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user_tb; //可以看到节点对提交事务没有任何影响
+------+--------+
| id | name |
+------+--------+
| 1 | 王五 |
| 2 | 赵六 |
+------+--------+
2 rows in set (0.00 sec)
mysql> rollback; //尝试在事务外回滚
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user_tb; //但实际并没有任何作用
+------+--------+
| id | name |
+------+--------+
| 1 | 王五 |
| 2 | 赵六 |
+------+--------+
2 rows in set (0.00 sec)
事务也可以一次写完提交,但需要修改结束字符,需要使用delimiter [新的字符]
注意:如果放回到设置的当前节点的上一个节点,那么当前节点就会被删除。但是返回到当前节点后继续向下操作,那么当前节点还可以使用。例如:一个事务存在开始节点、point1节点和point2节点,如果返回到了point1节点,那么point2节点就被删除无法使用;但是返回到point2节点后,向下操作,下次还可以返回到point2节点。