## 事务
事务是逻辑上的一组操作,组成这组操作的各个单元,要不全都成功要不全都失败。
**注意:** MySQL 数据库目前只有 innoDB 存储引擎支持事务。
### 事务的四大特性(ACID)
1. 原子性(atomicity): 一个事务必须视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚。
2. 一致性(consistency): 数据库总数从一个一致性的状态转换到另一个一致性的状态。
3. 隔离性(isolation): 一个事务所做的修改在最终提交以前,对其他事务是不可见的。
4. 持久性(durability): 一旦事务提交,则其所做的修改就会永久保存到数据库中。此时即使系统崩溃,修改的数据也不会丢失。
### 事务控制语句
BEGIN 或 START TRANSACTION 或 SET AUTOCOMMIT = 0;显示地开启一个事务;
COMMIT;提交事务,并使已对数据库进行的所有修改成为永久性的;
ROLLBACK;回滚事务,并撤销正在进行的所有未提交的修改;
SAVEPOINT identifier;在事务中创建一个保存点;
RELEASE SAVEPOINT identifier;删除一个事务的保存点; 当没有指定的保存点时,执行该语句会抛出一个异常;
ROLLBACK TO identifier;把事务回滚到标记点;
SET TRANSACTION; 设置事务的隔离级别。
### 事务示例
现实生活中存钱取钱的事务模拟:
```
// 创建数据表
CREATE TABLE IF NOT EXISTS account (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
name varchar(15) NOT NULL DEFAULT '',
balance decimal(10,2) unsigned NOT NULL DEFAULT '0.00',
PRIMARY KEY (id)
) ENGINE=InnoDB;
CREATE TABLE account_log (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
account_id int(10) unsigned NOT NULL DEFAULT '0',
amount decimal(10,2) NOT NULL DEFAULT '0.00'
PRIMARY KEY (id)
) ENGINE=InnoDB;
// 创建账户
insert into account (name) values('小明');
// 给小明账户存入 1000 元
start transaction;
insert into account_log (account_id, amount) values(1, 1000.00);
update account set balance = balance + 1000.00 where id = 1;
commit;
// 查验账户余额和存取记录
select * from account;
select * from account_log;
// 小明去取钱,按下提交按钮,突然停电了
start transaction;
insert into account_log (account_id, amount) values(1, -100.00);
update account set balance = balance - 100.00 where id = 1;
rollback;
// 查验账户余额和存取记录
select * from account;
select * from account_log;
```
参考链接:
- [MySQL事务](http://www.runoob.com/mysql/mysql-transaction.html)
- [通过例子理解事务的4种隔离级别](http://www.cnblogs.com/snsdzjlz320/p/5761387.html)