例如~ 當要轉帳時,會有一個交易資料,要從甲帳戶扣錢,把錢加到乙帳戶。如果這個交易從甲帳戶扣錢成功,結果乙帳戶的帳號錯誤,無法成功存入,怎麼辦?
如果有一個機制,可以把「從甲帳戶扣錢,把錢加到乙帳戶」當成一個完整的交易,只有兩個作業都成功,才進行交易(就是Commit),否則就取消交易(就是Rollback),這樣就不會出現錯誤。
要點 (1)
MySQL 常用的兩個資料表類型:MyISAM 不支援交易功能,所以以下的整理,均是針對 InnoDB 的DML指令而言,DDL 的指令就不能 ROLLBACK。
怎麼知道我的資料表是MyISAM還是InnoDB? 請參考 https://www.mysql.tw/2017/06/innodb-foreign-key.html
開始進入交易模式,可以使用 START TRANSACTION 或是 BEGIN,並等待COMMIT或是ROLLBACK來確定要不要確認交易。
要點 (2)
SET AUTOCOMMIT=1; 表示每次的指令自動確認 (不需要commit但是無法rollback)
SET AUTOCOMMIT=0; 表示每次的指令不會自動確認 (需要commit但是可以rollback)
SELECT @@AUTOCOMMIT; 可以查詢目前是否AUTOCOMMIT
因此要能夠使用rollback,必須讓AUTOCOMMIT=0
將 AUTOCOMMIT 改為 0 時,就算沒使用 START TRANSACTION 或 BEGIN ,整個連線執行的 SQL 指令,都會等到下達 COMMIT 提交後,才會真正儲存變更。也就是跟在交易模式下相同。
SELECT @@AUTOCOMMIT;
SELECT @AUTOCOMMIT;
SELECT AUTOCOMMIT;
SELECT @AUTOCOMMIT;
SELECT AUTOCOMMIT;
以上三個有何差異? @@AUTOCOMMIT指系統變數,@AUTOCOMMIT指自訂變數,最後一個則是錯誤的指令。
要點 (3)
交易過程中,可標示多個不同的儲存點,有需要時可 ROLLBACK 到某個儲存點。
建立儲存點:SAVEPOINT 名稱
刪除儲存點:RELEASE SAVEPOINT 名稱
ROLLBACK 到某個儲存點:ROLLBACK TO SAVEPOINT 名稱
如果建立新儲存點時,已有同名稱的舊儲存點,舊儲存點將被刪除,並建立新的儲存點。
範例 :
BEGIN;
INSERT INTO student VALUES(10, 'abc');
COMMIT;
範例 :
START TRANSACTION;
INSERT INTO student VALUES(10, 'abc');
COMMIT;
範例 :
START TRANSACTION;
SELECT @A:=SUM(salary) FROM table1 WHERE type=1;
UPDATE table2 SET summary=@A WHERE type=1;
COMMIT;
要點 (3)
交易過程中,可標示多個不同的儲存點,有需要時可 ROLLBACK 到某個儲存點。
建立儲存點:SAVEPOINT 名稱
刪除儲存點:RELEASE SAVEPOINT 名稱
ROLLBACK 到某個儲存點:ROLLBACK TO SAVEPOINT 名稱
如果建立新儲存點時,已有同名稱的舊儲存點,舊儲存點將被刪除,並建立新的儲存點。
範例 :
BEGIN;
INSERT INTO student VALUES(10, 'abc');
COMMIT;
範例 :
START TRANSACTION;
INSERT INTO student VALUES(10, 'abc');
COMMIT;
範例 :
START TRANSACTION;
SELECT @A:=SUM(salary) FROM table1 WHERE type=1;
UPDATE table2 SET summary=@A WHERE type=1;
COMMIT;
範例 :
BEGIN;
INSERT INTO testtable (id, t) VALUES(1, 10);
SAVEPOINT p1;
UPDATE student SET t=20 WHERE id=1;
ROLLBACK TO SAVEPOINT p1;
COMMIT;
更多參考資料
https://xyz.cinc.biz/2013/05/mysql-transaction.html
https://blog.longwin.com.tw/2006/03/innodb_transaction_2006/
INSERT INTO testtable (id, t) VALUES(1, 10);
SAVEPOINT p1;
UPDATE student SET t=20 WHERE id=1;
ROLLBACK TO SAVEPOINT p1;
COMMIT;
更多參考資料
https://xyz.cinc.biz/2013/05/mysql-transaction.html
https://blog.longwin.com.tw/2006/03/innodb_transaction_2006/
0 留言