資料庫中為什麼需要Implict Commit(隱式提交事務),implictcommit

來源:互聯網
上載者:User

資料庫中為什麼需要Implict Commit(隱式提交事務),implictcommit

先看一段SQL,最後一條SQL的輸出你認為是什嗎?

SET AUTOCOMMIT = 1;BEGIN;INSERT INTO t1 VALUES (1);CREATE TABLE t2 (pk int primary key);INSERT INTO t2 VALUES (2);ROLLBACK;SHOW TABLES;


答案是:t1, t2都存在!

mysql> show tables;+----------------+| Tables_in_test |+----------------+| t1             || t2             |+----------------+2 rows in set (0.00 sec)

更奇怪的是:t1中的1也插入成功了!

mysql> select * from t1;+----+| pk |+----+|  1 |+----+1 row in set (0.00 sec)


為什麼ROLLBACK沒有生效呢?答案是: Implict Commit
執行CREATE TABLE語句前,之前的事務被隱式提交。因為AUTOCOMMIT=1,所以提交後也不會自動新建立任何事務,INSERT語句執行後立即提交,ROLLBACK不會作用在任何事務上,所以得到了我們最後看到的結果。


稍微改一下,讓AUTOCOMMIT=0,會怎樣呢?

SET AUTOCOMMIT = 0;BEGIN;INSERT INTO t1 VALUES (1);CREATE TABLE t2 (pk int primary key);INSERT INTO t2 VALUES (2);ROLLBACK;SHOW TABLES;


答案是:t1, t2都存在!插入到t1中的1被提交(插入成功)但插入到t2中得2被復原(沒有插入成功)。之所以t1中的1被提交,是因為CREATE TABLE導致ImplictCOMMIT(注意,是COMMIT,不是ROLLBACK哦!),執行INSERT的時候,會自動開啟一個新事務(AUTOCOMMIT=0的語義要求的行為)。所以t2中的2被ROLLBACK復原。


為什麼部分操作會導致Implict Commit?為什麼這樣設計?
為了保證直觀上的原子性。假設不做Implict Commit,看看上面的語句會怎樣:使用者的心理預期是復原t1的INSERT操作,以及t2的CREATE操作,INSERT操作。如果我們有能力做到這樣,那的確是很完美的。但實際上我們很難做到,特別是在分布式系統中更難!因為CREATE TABLE操作背後涉及到了大量的操作,不僅僅包括對核心表的操作,還包括大量記憶體資料結構的更新(如Schema),以及儲存系統的變更(如建立相應的資料區塊),工程上很難把這些操作做成原子的。


那麼,應該如何做呢?比較折中的方式就是跟使用者做一個約定:CREATE TABLE操作總預設COMMIT它之前的事務,這就是implict commit。

從MySQL文檔看,他們做這一塊的時候遇到了很多問題,至少在這裡踩過兩個坑。並且,隨著版本的進化,他們還不斷的讓更多語句能引發implict commit。到底哪些語句會引發implict commit,請參考MySQL文檔: http://dev.mysql.com/doc/refman/5.1/en/implicit-commit.html




相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.