一、什么是事务
事务是一组SQL语句构成的语句集合,它保证所有的SQL都能全部执行或者全部不执行。
事务必须满足四个条件(ACID):Atomicity 原子性
Consistency 一致性
Isolation 隔离性
Durability 持久性
- 原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
- 一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
- 隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
- 持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
工作流程为:
MySQL对事务的支持与引擎有关:
- MyISAM:不支持事务,用于只读程序提高性能。
- InnoDB:支持ACID事务、行级锁、并发。
- Berkeley DB:支持事务。
二、使用方法
执行事务的方法很简单,只要在需要执行的SQL语句前后分别加上BEGIN
和COMMIT
即可,即:
1 2 3 4 5 |
BEGIN; SQL 1; SQL 2; ... COMMIT; |
默认情况下,SQL语句都是默认提交的,即每次执行SQL语句后都会自动加上提交动作。使用
set autocommit = 0
命令可将语句设置成不自动提交。
三、示例
1.创建一张测试表
1 2 3 4 5 6 |
mysql> create table test( -> id int primary key auto_increment, -> name varchar(20) not null default "", -> age tinyint unsigned not null -> ); Query OK, 0 rows affected (0.22 sec) |
在不使用事务的情况下插入一行数据:
1 2 3 4 5 6 7 8 9 10 |
mysql> insert into test values(1, "maqian", 21); Query OK, 1 row affected (0.07 sec) mysql> select * from test; +----+--------+-----+ | id | name | age | +----+--------+-----+ | 1 | maqian | 21 | +----+--------+-----+ 1 row in set (0.00 sec) |
2.使用事务插入一行数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
-- 开始事务 mysql> begin; Query OK, 0 rows affected (0.00 sec) -- 插入数据 mysql> insert into test values(2, "xiaoming", 20); Query OK, 1 row affected (0.00 sec) -- 查看当前数据 mysql> select * from test; +----+----------+-----+ | id | name | age | +----+----------+-----+ | 1 | maqian | 21 | | 2 | xiaoming | 20 | +----+----------+-----+ 2 rows in set (0.00 sec) -- 提交 mysql> commit; Query OK, 0 rows affected (0.03 sec) -- 数据仍然存在 mysql> select * from test; +----+----------+-----+ | id | name | age | +----+----------+-----+ | 1 | maqian | 21 | | 2 | xiaoming | 20 | +----+----------+-----+ 2 rows in set (0.00 sec) |
3.回滚事务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
mysql> insert into test values(3, "xiaohua", 1); Query OK, 1 row affected (0.00 sec) -- 插入了一行数据 mysql> select * from test; +----+----------+-----+ | id | name | age | +----+----------+-----+ | 1 | maqian | 21 | | 2 | xiaoming | 20 | | 3 | xiaohua | 1 | +----+----------+-----+ 3 rows in set (0.00 sec) -- 回滚 mysql> rollback; Query OK, 0 rows affected (0.02 sec) -- 被插入的行被回滚了,数据库回到插入前的状态 mysql> select * from test; +----+----------+-----+ | id | name | age | +----+----------+-----+ | 1 | maqian | 21 | | 2 | xiaoming | 20 | +----+----------+-----+ 2 rows in set (0.00 sec) |
评论