MySQL SET autocommit

2013-05-27_141127

這是MySQL 5實力養成暨評量裡的8-54.『在MySQL中要啟動交易(transaction)功能,下列指令何者正確?』

答案:(D) SET AUTOCOMMIT = 0

這實在是很詭異?上次在乖乖牌資料庫發生了人間交易慘劇提過,但是好像沒有分享很透徹,而且這一個題意還真讓人看不懂,真不知是ㄚ琪的語文造詣有問題,還是出題者的中文有問題,只能說大家小心了,今天我們再詳細分享手冊這一節的所有部份,並且好好地思索出題者的原意是怎樣。

冊的MySQL 5.7 Reference Manual :: 13 SQL Statement Syntax :: 13.3 MySQL Transactional and Locking Statements :: 13.3.1 START TRANSACTION, COMMIT, and ROLLBACK Syntax的說明

或是簡體中文版的MySQL 5.1参考手册::13. SQL语句语法::13.4. MySQL事務處理和鎖定語句::13.4.1. START TRANSACTION, COMMIT和ROLLBACK語法

轉譯繁體如下:

START TRANSACTION | BEGIN [WORK]
COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
SET AUTOCOMMIT = {0 | 1}

START TRANSACTION或BEGIN語句可以開始一項新的交易。COMMIT可以提交當前交易,是變更成為永久變更。ROLLBACK可以 回滾當前交易,取消其變更。SET AUTOCOMMIT語句可以禁用或啟用預設的autocommit模式,用於當前連接

自選的WORK關鍵詞被支援,用於COMMIT和RELEASE,與CHAIN和RELEASE子句。CHAIN和RELEASE可以被用於對交易完成進行附加控制。Completion_type系統變數的值決定了預設完成的性質。請參見5.3.3節,「伺服器系統變數」

AND CHAIN子句會在當前交易結束時,立刻啟動一個新交易,並且新交易與剛結束的交易有相同的隔離等級。RELEASE子句在終止了當前交易後,會讓伺服器中斷與當前客戶端的連接。包含NO關鍵詞可以抑制CHAIN或RELEASE完成。如果completion_type系統變數被設置為一定的值,使連鎖或釋放完成可以預設進行,此時NO關鍵詞有用。

預設情況下,MySQL採用autocommit模式運行。這意味著,當您執行一個用於更新(修改)資料表的語句之後,MySQL立刻把更新儲存到磁盤中。

如果您正在使用一個交易安全型的儲存引擎(如InnoDB, BDB或NDB叢集),則您可以使用以下語句禁用autocommit模式:

SET AUTOCOMMIT=0;

通過把AUTOCOMMIT變數設置為零,禁用autocommit模式之後,您必須使用COMMIT把變更儲存到磁盤中,或著如果您想要忽略從交易開始進行以來做出的變更,使用ROLLBACK。

如果您想要對於一個單一系列的語句禁用autocommit模式,則您可以使用START TRANSACTION語句:

START TRANSACTION;
SELECT @A:=SUM(salary) FROM table1 WHERE type=1;
UPDATE table2 SET summary=@A WHERE type=1;
COMMIT;

使用START TRANSACTION,autocommit仍然被禁用,直到您使用COMMIT或ROLLBACK結束交易為止。然後autocommit模式恢復到原來的狀態。

BEGIN和BEGIN WORK被作為START TRANSACTION的別名受到支援,用於對事務進行初始化。START TRANSACTION是標準的SQL語法,並且是啟動一個ad-hoc交易的推薦方法。BEGIN語句與BEGIN關鍵詞的使用不同。BEGIN關鍵詞可以啟動一個BEGIN…END複合語句。後者不會開始一項交易。請參見20.2.7節,「BEGIN … END復合語句」

您也可以按照如下方法開始一項交易:

START TRANSACTION WITH CONSISTENT SNAPSHOT;

WITH CONSISTENT SNAPSHOT子句用於啟動一個一致的讀取,用於具有此類功能的儲存引擎。目前,該子句只適用於InnoDB。該子句的效果與發佈一個START TRANSACTION,後面跟一個來自任何InnoDB資料表的SELECT的效果一樣。請參見15.2.10.4節,「一致的非鎖定讀」

開始一項交易會造成一個隱含的UNLOCK TABLES被執行。

為了獲得最好的結果,交易應只使用由單一交易儲存引擎管理的資料表執行。否則,會出現以下問題:

·         如果您使用的資料表來自多個交易安全型儲存引擎(例如InnoDB和BDB),並且交易隔離等級不是SERIALIZABLE,則有可能當一個交易提交時,其它正在進行中的、使用同樣的資料表的交易將只會發生由第一個交易產生的變更。也就是,用混合引擎不能保證交易的原子性,並會造成不一致。(如果混合引擎交易不經常有,則您可以根據需要使用SET TRANSACTION ISOLATION LEVEL把隔離等級設置到SERIALIZABLE。)

·         如果您在交易中使用非交易安全型資料表,則對這些資料表的任何變更被立刻儲存,不論autocommit模式的狀態如何。

如果您在更新了交易中一個交易資料表之後,發佈一個ROLLBACK語句,則會出現一個ER_WARNING_NOT_COMPLETE_ROLLBACK警告。對交易安全型資料表的變更被回滾,但是對非交易安全型資料表沒有變更。

每個交易被儲存在一個組塊中的二進制日誌中,在COMMIT之上。被回滾的交易不被計入日誌。(例外情況:對非交易資料表的更改不會被 回滾。如果一個被回滾的交易包括對非交易資料表的更改,則整個交易使用一個在末端的ROLLBACK語句計入日誌,以確保對這些資料表的更改進行複製。)見5.11.3節,「二進制日誌」

您可以使用SET TRANSACTION ISOLATION LEVEL更改交易的隔離等級。請參見13.4.6節,「SET TRANSACTION語法」

回滾可以慢速運行。在用戶沒有明確要求時,也可以進行回滾(例如,當錯誤發生時)。因此,在明確地和隱含的(ROLLBACK SQL命令)回滾時,SHOW PROCESSLIST會在Stage列中顯示Rolling back,用於連接。

感謝你看到這裡,很快就可以離開了,但最好的獎勵行動就是按一下幫我分享或留言,感恩喔~

點我分享到Facebook

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *