MySQL事务嵌套
前言
MySQL 在開始某個事務的時候,會隱式提交上一個事務。所以 MySQL 本身是不支持事務嵌套的。
但 MySQL 也給我們提供了一個 SAVEPOINT 來做出類似事務嵌套的動作,我們將運用 SAVEPOINT 來幫助我們實現事務嵌套。
MySQL示例
準備一張表,用于測試。
CREATE TABLE `demo_transaction` (`id` int(11) NOT NULL,PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;部分回滾
-- 格式化 TRUNCATE demo_transaction;-- 開啟事務 BEGIN;-- 插入一條數據 INSERT INTO `demo_transaction`(id) VALUES(1);-- 開啟 SAVEPOINT SAVEPOINT t1; INSERT INTO `demo_transaction`(id) VALUES(2); -- 回滾 SAVEPOINT ROLLBACK TO SAVEPOINT t1;-- 提交事務 COMMIT;這時候,查詢一下表 demo_transaction,會看到表里只有一條數據。
因為 2 的那條數據已經被回滾了。
全部提交
-- 格式化 TRUNCATE demo_transaction;-- 開啟事務 BEGIN;-- 插入一條數據 INSERT INTO `demo_transaction`(id) VALUES(1);-- 開啟 SAVEPOINT SAVEPOINT t1; INSERT INTO `demo_transaction`(id) VALUES(2); -- 釋放 SAVEPOINT RELEASE SAVEPOINT t1;-- 提交事務 COMMIT;這時候,查詢一下表 demo_transaction,會看到表里有兩條數據。
全部回滾
-- 格式化 TRUNCATE demo_transaction;-- 開啟事務 BEGIN;-- 插入一條數據 INSERT INTO `demo_transaction`(id) VALUES(1);-- 開啟 SAVEPOINT SAVEPOINT t1; INSERT INTO `demo_transaction`(id) VALUES(2); -- 釋放 SAVEPOINT RELEASE SAVEPOINT t1;-- 提交事務 ROLLBACK;這時候,查詢一下表 demo_transaction,會看到表里沒有數據。
PHP實現
<?php /*** Transactions*/ trait Transactions {/*** transaction nums** @var integer*/protected $transactionNums = 0;/*** begin transaction*/public function beginTrans(){++$this->transactionNums;if ($this->transactionNums == 1) {$this->getDB()->beginTransaction();} else {$this->query("ROLLBACK TO SAVEPOINT trans{$this->transactionNums}");}}/*** rollback transaction*/public function rollback(){if ($this->transactionNums > 1) {$this->query("SAVEPOINT trans{$this->transactionNums}");} else {$this->getDB()->rollback();}--$this->transactionNums;}/*** commit transaction*/public function commit(){while ($this->transactionNums > 1) {$this->query("RELEASE SAVEPOINT trans{$this->transactionNums}");--$this->transactionNums;}if ($this->transactionNums) {$this->getDB()->commit();}$this->transactionNums = 0;} }最后
梳理一下知識,免于踩坑。
總結
- 上一篇: 在Ubuntu中编译运行C语言
- 下一篇: 最简单的基于FFMPEG+SDL的音频播