程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> DB2數據庫 >> DB2教程 >> 數據庫中為什麼需要ImplictCommit(隱式提交事務)

數據庫中為什麼需要ImplictCommit(隱式提交事務)

編輯:DB2教程

數據庫中為什麼需要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。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved