事務( transaction)是一個邏輯操作的最小單位,具體的在數據庫中的是指一組操作的sql語句,這組sql在執行時要全部成功,纔可以提交(commit)操作的數據,一旦有任何一條失敗,則要回滾,所有sql操作均失去效果。
在MySQL中,操作的sql語句默認是自動提交的,同時還提供begin和start transaction方式來開啓事務,實現手動提交(commit),只有沒有提交的操作纔可以回滾(rollback)。接下來就來逐一介紹它們具體的使用方法和操作需要注意的“坑”。
一.autocommit參數
autocommit決定了MySQL中是否在執行完一條數據後可以直接提交結果,在MySQL中默認的是1,即開啓自動提交,當將它的值設置爲0時,便不會自動提交,在執行SQL之後,就可以手動提交或者選擇回滾。
(一)查看autocommit的值,進入MySQL數據庫中,使用
SELECT @@autocommit;
來查看相關@autocommit的值
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 1 |
+--------------+
1 row in set (0.00 sec)
這裏可以看到,值=1,也就是默認的開啓自動提交的,但要實現事務,我們要關閉自動提交。
(二)設置autocommit的值來關閉自動提交。使用
set autocommit=0;
將其值設置爲0,從而關閉自動提交。
mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 0 |
+--------------+
1 row in set (0.00 sec)
這樣,在我們執行sql語句後,就需要手動提交,不然不會修改結果。
(三)commit和rollback的效果展示
+-------+------+-------+
| name | age | id |
+-------+------+-------+
| curry | 15 | 10001 |
+-------+------+-------+
這是一個user表,裏面有name,age,id字段。首先給這個表中添加一個數據
mysql> insert into user values('tom',10,2);
Query OK, 1 row affected (0.01 sec)
這裏我們看到已經添加成功了,但是數據真的保存了嗎?select一下看看
mysql> select * from user;
+-------+------+-------+
| name | age | id |
+-------+------+-------+
| tom | 10 | 2 |
| curry | 15 | 10001 |
+-------+------+-------+
3 rows in set (0.00 sec)
發現確實在表裏了,但這裏也是沒有提交的,回滾一下會怎麼樣?
mysql> rollback;
Query OK, 0 rows affected (0.01 sec)
mysql> select * from user;
+-------+------+-------+
| name | age | id |
+-------+------+-------+
| curry | 15 | 10001 |
+-------+------+-------+
2 rows in set (0.00 sec)
tom的信息沒有了,這就是通過設置autocommit=0,從而關閉自動提交,然後通過回滾實現事務的一種方式。但這有一個問題,就是設置了這個參數後,整個數據庫在提交操作的時候都需要手動提交,很麻煩。MySQL很貼心的提供了begin和start transaction方法,真正實現操作一組數據,對於報錯的手動回滾!
二、begin
在要寫sql語句之前,先使用
mysql> begin;
Query OK, 0 rows affected (0.01 sec)
mysql> insert into user values('tom',10,2);
Query OK, 1 row affected (0.01 sec)
mysql> select * from user;
+-------+------+-------+
| name | age | id |
+-------+------+-------+
| tom | 10 | 2 |
| curry | 15 | 10001 |
+-------+------+-------+
3 rows in set (0.00 sec)
插入了,那能不能使用rollback回滾那?
mysql> rollback;
Query OK, 0 rows affected (0.01 sec)
mysql> select * from user;
+-------+------+-------+
| name | age | id |
+-------+------+-------+
| curry | 15 | 10001 |
+-------+------+-------+
成功回滾,下面的start transaction方法和這個使用步驟一樣。
三、start transaction
在這裏,我們就不直接回滾,我們操作完sql之後,手動提交,然後回滾看看效果!
首選使用start transaction
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
插入數據
mysql> insert into user values('tom',10,2);
Query OK, 1 row affected (0.00 sec)
mysql> select * from user;
+-------+------+-------+
| name | age | id |
+-------+------+-------+
| tom | 10 | 2 |
| curry | 15 | 10001 |
+-------+------+-------+
3 rows in set (0.00 sec)
手動提交
mysql> commit;
Query OK, 0 rows affected (0.01 sec)
然後回滾,並查看結果
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user;
+-------+------+-------+
| name | age | id |
+-------+------+-------+
| tom | 10 | 2 |
| curry | 15 | 10001 |
+-------+------+-------+
3 rows in set (0.00 sec)
可以看到,一旦提交,是不可以回滾的,在沒有提交之前,可以通過回滾撤回操作不保留sql效果!下一節詳細介紹事務的四大特性和事務的隔離級別以及會出現的問題等。
下一節:MySQL數據庫中的事務特性和事務的隔離級別問題