## 事務
事務是邏輯上的一組操作,組成這組操作的各個單元,要不全都成功要不全都失敗。
**注意:** 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)