事務是個啥?
事務(Transaction)一般是指要做的或所做的事情。數據庫事務(Database Transaction)是由SQL語句組成的邏輯處理單元。一個事務是一條SQL語句或一組SQL語句組成的。事務中的SQL語句就是一個整體,事務中語句全部正確,執行事務,若有一條出錯,則事務中的語句全部不執行。
MySQL事務常用於操作量大,複雜性高的數據,避免因誤操作而出現數據信息異常,確保了數據的一致性和完整性。
事務的四大特性(ACID)
1.原子性[不可分割性](Atomicity):一個事務中的所有操作,要麼全部執行,要麼全部不執行,不存在只執行部分語句情況。若事務在執行過程中出現錯誤,則會被回滾(Rollback)到事務開始前的狀態,並不會對數據進行實際更改。
2.一致性(Consistency):事務開始前,數據庫處於一個一致性狀態,事務結束後,數據庫必須也處於一致性狀態。例如:銀行轉賬後,兩個賬戶金額之和與轉賬前相同。
3.隔離性[獨立性](Isolation):避免一個事務執行時被其他事務所幹擾。即一個事務中的操作對其他事務是隔離的,各個事務之間不能互相干擾。
4.持久性(Durability):一個事務提交之後,對數據庫的修改就是永久的,即使服務宕掉也可以進行數據恢復。
提交方式
1)自動提交,這是MySQL數據庫的默認提交事務的方式,即輸入完SQL語句後,回車自動提交事務。
2)手動提交,通過修改將默認提交方式改爲手動提交,把SQL語句輸入完之後,執行commit;纔將其提交,否則一直不提交。
注意事項
1)MySQL 中只有使用了 Innodb 和bdb存儲引擎的數據庫或表才支持事務。
2)對於少量的數據更新,建議不使用事務,直接輸入SQL語句更加快捷。
3)事務中的SQL語句要麼全部執行,要麼全部不執行,寫入時儘量避免語句錯誤。
事務控制語句
事務控制語句是使用事務的基礎,務必牢記。
BEGIN或START TRANSACTION:開啓一個事務。
ROLLBACK或ROLLBACK WORK:手動回滾,結束用戶的事務,還原到創建事務之前的狀態。
SAVEPOINT EnglishNUM:在事務中創建保存點,可以通過回滾恢復到保存點的位置。
COMMIT或COMMIT WORK:提交事務,並將數據庫進行的所有操作永久修改。
RELEASE SAVEPOINT EnglishNUM:刪除一個事務的保存點。
ROLLBACK TO EnglishNUM:把事務回滾到指定保存點位置。
事務實際應用
創建一個表,並在其中插入一些數據,用於測試。
mysql> create table test(id int auto_increment primary key,name varchar(6) not null,age tinyint unsigned not null);
mysql> insert into test values(1,'張三',23),(2,'李四',24),(3,'王五',25);
查看錶中記錄
mysql> select * from test;
+----+--------+-----+
| id | name | age |
+----+--------+-----+
| 1 | 張三 | 23 |
| 2 | 李四 | 24 |
| 3 | 王五 | 25 |
+----+--------+-----+
事務操作案例
接下來就開始測試了
創建事務:begin或start transaction
提交事務:commit
mysql> begin;
開啓事務後,在其中進行的操作在沒有提交之前,是不會對數據庫的實際數據進行修改的,在事務中的查看是將你操作後的效果顯示出來罷了。對於謹慎操作時,還是比較有效果的。
mysql> delete from test where id=1; 刪除id爲1的記錄
mysql> select * from test; 在事務中查看test表記錄
+----+--------+-----+
| id | name | age |
+----+--------+-----+
| 2 | 李四 | 24 |
| 3 | 王五 | 25 |
+----+--------+-----+
在事務中查看,id爲1的記錄是已經消失了,但新建一個終端,登錄到數據庫中查看,發現id爲1的記錄依然存在。
mysql> select * from test;
+----+--------+-----+
| id | name | age |
+----+--------+-----+
| 1 | 張三 | 23 |
| 2 | 李四 | 24 |
| 3 | 王五 | 25 |
+----+--------+-----+
回到創建了事務的終端,將事務提交後,發現操作纔會實際執行,也就是刪除id爲1的記錄。
mysql> commit;
mysql> select * from test;
+----+--------+-----+
| id | name | age |
+----+--------+-----+
| 2 | 李四 | 24 |
| 3 | 王五 | 25 |
+----+--------+-----+
回滾操作案例
在使用回滾(rollback)的時候需要注意,回滾只在事務中才會生效,若事務已經提交,則對數據的修改是永久的,無法通過回滾還原。
回滾:rollback
查看test表記錄
mysql> select * from test;
+----+--------+-----+
| id | name | age |
+----+--------+-----+
| 2 | 李四 | 24 |
| 3 | 王五 | 25 |
+----+--------+-----+
創建一個事務,並對數據進行修改
mysql> begin;
mysql> update test set name='張三' where id=2;
mysql> update test set name='趙六' where id=3;
將姓名修改後,查看test表記錄
mysql> select * from test;
+----+--------+-----+
| id | name | age |
+----+--------+-----+
| 2 | 張三 | 24 |
| 3 | 趙六 | 25 |
+----+--------+-----+
想要將一切都還原,只需要將回滾一下就可以了。
mysql> rollback;
mysql> select * from test;
+----+--------+-----+
| id | name | age |
+----+--------+-----+
| 2 | 李四 | 24 |
| 3 | 王五 | 25 |
+----+--------+-----+
這樣一切都還原到創建事務之前的狀態了,沒有對數據進行任何操作,也可以將事務提交,並且不會出現報錯。
mysql> commit;
回滾點操作案例
對於回滾操作,還是有些死板的,畢竟直接回滾會將事務中所有的SQL語句刪除,而創建回滾點(Rollback point)就不一樣了,將任務輸入一半時,可以創建一個回滾點,那麼後續的SQL語句出錯,回滾到保存的回滾點,就可以少輸入一半的SQL語句,但要注意,雖說回滾點可以存在多個,但只能回滾1次。
創建回滾點:savepoint 英文字母數字
轉到回滾點:rollback to 英文字母數字
還是先查看test表記錄
mysql> select * from test;
+----+--------+-----+
| id | name | age |
+----+--------+-----+
| 2 | 李四 | 24 |
| 3 | 王五 | 25 |
+----+--------+-----+
先創建一個回滾點
mysql> savepoint a1;
接着對記錄進行修改操作
mysql> update test set name='哈哈哈' where id=2;
mysql> update test set name='嘿嘿嘿' where id=3;
創建第二個回滾點
mysql> savepoint a2;
刪除一條記錄
mysql> delete from test where id=3;
查看修改後的test表記錄
mysql> select * from test;
+----+-----------+-----+
| id | name | age |
+----+-----------+-----+
| 2 | 哈哈哈 | 24 |
+----+-----------+-----+
接下來就可以通過回滾點進行回滾。
在回滾的時候需要注意,可以按照倒序的方式進行回滾,也就是有1,2兩個回滾點,先回滾2,再回滾1。
而另一種方式是按照順序進行回滾,先回滾1,但是2就無法進行回滾了,回滾到1後,其中保存的只是回滾點1中的之前的數據,並沒有回滾點2中的數據。簡單點來說,就是遊戲的存檔,你打完第一關存檔,打完第二關也存檔,當你回到第一關存檔中後,你還需要從新過第二關是一個道理。
轉到回滾點2中
mysql> rollback to a2;
mysql> select * from test;
+----+-----------+-----+
| id | name | age |
+----+-----------+-----+
| 2 | 哈哈哈 | 24 |
| 3 | 嘿嘿嘿 | 25 |
+----+-----------+-----+
轉到會滾點1中
mysql> rollback to a1;
mysql> select * from test;
+----+--------+-----+
| id | name | age |
+----+--------+-----+
| 2 | 李四 | 24 |
| 3 | 王五 | 25 |
+----+--------+-----+
刪除回滾點
最後將創建的回滾點刪除
mysql> release savepoint a1;