作者在之前的文章 “MySQL事務及為何不能在PHP模仿事務” 裡面, 詳細說明了事務的優點,並介紹了一些簡單的SQL命令,使得應用程序更加健壯。但在web程序員的生命旅程中並沒有多少事情是看起來那樣簡單的。。。。。
很遺憾滴通知你, 並不是所有的數據庫操作都支持回滾( ROLLBACK ) 。如果你更改數據庫/表結構(schema), 所有當前事務都會被提交, 而升級(alteration )將會在其獨有的事務中運行(不屬於任何客戶端事務)。這些語句包括:
CREATE DATABASE ALTER DATABASE DROP DATABASE CREATE TABLE ALTER TABLE DROP TABLE RENAME TABLE TRUNCATE TABLE CREATE INDEX DROP INDEX CREATE EVENT DROP EVENT CREATE FUNCTION DROP FUNCTION CREATE PROCEDURE DROP PROCEDURE我們不能撤消數據庫根本上的變化, 例如:
START TRANSACTION; DROP TABLE MyImportantData; -- 所有事務會被強制提交, existing (empty) transaction is COMMIT-ed -- 然後該表就被永久地刪除了(table is dropped permanently) ROLLBACK; -- 沒機會了,數據已經不要你了. no chance, mate - your data's gone
提示: 臨時表(TEMPORARY)
創建、升級和刪除(CREATE, ALTER, and DROP)臨時表並不會引起隱式提交(implicit COMMIT. )。當然,這些操作也是不能回滾的。
我們對異常那是愛之深責之切,那麼讓我們來看看另一個設計優美的部分。保存點(Savepoint)是事務中有效的命名位置。你可以回滾到某個保存點而不影響改點之前的SQL更新。。。有點像Photoshop中的歷史面板。
最簡單的方法,我們一起來看個示例:
START TRANSACTION; -- 增加 tableA 的記錄 INSERT INTO tableA VALUES (1,2,3); -- 創建保存點 tableAupdated SAVEPOINT tableAupdated; -- 增加 tableB 的記錄 INSERT INTO tableB VALUES (4,5,6); -- 反正發生了些什麼不愉快的事,要取消對 tableB 所做的更新... ROLLBACK TO tableAupdated; -- 這時候提交,就只有 tableA 被更新了 COMMIT;
當然, 也可以設置多個保存點標識符(SAVEPOINT identifiers), 並且在事務中回滾到任意一處。
也可以刪除一個保存點,語法如下:
RELEASE SAVEPOINT savepointName;
只要事務提交或者(整個)回滾,那麼所有的保存點都會被刪除。
事務和保存點的使用非常簡單,能有效保護 InnoDB 中重要的數據。你還有什麼理由堅持使用 MyISAM 呢,現在MyISAM的效率也不如InnoDB了。