START TRANSACTION
[transaction_characteristic [, transaction_characteristic] ...]
transaction_characteristic: {
WITH CONSISTENT SNAPSHOT
| READ WRITE
| READ ONLY
}
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
停用或啟用目前連線的預設自動提交模式。
預設情況下,MySQL 在啟用 自動提交 模式下執行。這表示,當未在交易內時,每個陳述式都是原子性的,就好像它被 START TRANSACTION
和 COMMIT
包圍一樣。您不能使用 ROLLBACK
來還原效果;然而,如果在陳述式執行期間發生錯誤,則會回滾該陳述式。
若要為單一系列的陳述式隱式停用自動提交模式,請使用 START TRANSACTION
陳述式
START TRANSACTION;
SELECT @A:=SUM(salary) FROM table1 WHERE type=1;
UPDATE table2 SET summary=@A WHERE type=1;
COMMIT;
使用 START TRANSACTION
,自動提交會保持停用狀態,直到您使用 COMMIT
或 ROLLBACK
結束交易為止。然後,自動提交模式會回復到其先前的狀態。
START TRANSACTION
允許數個修飾符來控制交易特性。若要指定多個修飾符,請用逗號分隔它們。
WITH CONSISTENT SNAPSHOT
修飾符為能夠支援它的儲存引擎啟動 一致讀取。這僅適用於InnoDB
。效果與發出START TRANSACTION
後接著從任何InnoDB
表中SELECT
相同。請參閱第 17.7.2.3 節〈一致非鎖定讀取〉。WITH CONSISTENT SNAPSHOT
修飾符不會變更目前的交易隔離層級,因此只有在目前隔離層級允許一致讀取時,它才會提供一致的快照。唯一允許一致讀取的隔離層級是REPEATABLE READ
。對於所有其他隔離層級,WITH CONSISTENT SNAPSHOT
子句會被忽略。當WITH CONSISTENT SNAPSHOT
子句被忽略時,會產生警告。READ WRITE
和READ ONLY
修飾符設定交易存取模式。它們允許或禁止變更交易中使用的表。READ ONLY
限制會阻止交易修改或鎖定對其他交易可見的交易和非交易表;交易仍然可以修改或鎖定暫存表。當已知交易為唯讀時,MySQL 會為
InnoDB
表上的查詢啟用額外的最佳化。指定READ ONLY
可確保在無法自動判斷唯讀狀態的情況下套用這些最佳化。如需更多資訊,請參閱第 10.5.3 節〈最佳化 InnoDB 唯讀交易〉。如果未指定存取模式,則會套用預設模式。除非預設已變更,否則它是讀取/寫入。不允許在同一個陳述式中同時指定
READ WRITE
和READ ONLY
。在唯讀模式中,仍然可以使用 DML 陳述式來變更使用
TEMPORARY
關鍵字建立的表。使用 DDL 陳述式所做的變更是不允許的,就像永久表一樣。如需關於交易存取模式的其他資訊,包括變更預設模式的方式,請參閱第 15.3.7 節〈SET TRANSACTION 陳述式〉。
如果啟用
read_only
系統變數,則明確使用START TRANSACTION READ WRITE
開始交易需要CONNECTION_ADMIN
權限(或已棄用的SUPER
權限)。
許多用於編寫 MySQL 用戶端應用程式的 API(例如 JDBC)提供自己的開始交易方法,這些方法可以(有時應該)用來代替從用戶端傳送 START TRANSACTION
陳述式。如需更多資訊,請參閱第 31 章《連接器和 API》或您的 API 文件。
若要明確停用自動提交模式,請使用下列陳述式
SET autocommit=0;
將 autocommit
變數設定為零來停用自動提交模式後,對交易安全表(例如 InnoDB
或 NDB
的表)所做的變更不會立即永久生效。您必須使用 COMMIT
將您的變更儲存到磁碟,或使用 ROLLBACK
忽略這些變更。
autocommit
是一個連線變數,必須為每個連線設定。若要為每個新連線停用自動提交模式,請參閱autocommit
系統變數在第 7.1.8 節〈伺服器系統變數〉中的描述。
BEGIN
和 BEGIN WORK
支援作為 START TRANSACTION
的別名,用於啟動交易。START TRANSACTION
是標準 SQL 語法,是啟動臨時交易的建議方式,並且允許 BEGIN
不允許的修飾符。
BEGIN
陳述式與啟動 BEGIN ... END
複合陳述式的 BEGIN
關鍵字用法不同。後者不會開始交易。請參閱第 15.6.1 節〈BEGIN ... END 複合陳述式〉。
在所有已儲存的程式(已儲存的程序和函數、觸發程序和事件)中,剖析器會將 BEGIN [WORK]
視為 BEGIN ... END
區塊的開頭。請改用 START TRANSACTION
在此內容中開始交易。
針對 COMMIT
和 ROLLBACK
,支援選用的 WORK
關鍵字,以及 CHAIN
和 RELEASE
子句。CHAIN
和 RELEASE
可以用於對交易完成的額外控制。completion_type
系統變數的值決定預設完成行為。請參閱第 7.1.8 節〈伺服器系統變數〉。
AND CHAIN
子句會導致新的交易在目前交易結束後立即開始,且新交易與剛終止的交易具有相同的隔離層級。新交易也會使用與剛終止交易相同的存取模式(READ WRITE
或 READ ONLY
)。RELEASE
子句會導致伺服器在終止目前交易後中斷目前用戶端連線。如果預設將 completion_type
系統變數設定為導致鏈結或釋放完成,則包含 NO
關鍵字會抑制 CHAIN
或 RELEASE
完成,這會很有用。
開始交易會導致任何擱置的交易被提交。如需更多資訊,請參閱第 15.3.3 節〈導致隱式提交的陳述式〉。
開始交易也會導致使用 LOCK TABLES
取得的表鎖定被釋放,就好像您已執行 UNLOCK TABLES
一樣。開始交易不會釋放使用 FLUSH TABLES WITH READ LOCK
取得的全域讀取鎖定。
為了獲得最佳結果,交易應僅使用單一交易安全儲存引擎管理的表來執行。否則,可能會發生下列問題
如果您使用來自多個交易安全儲存引擎(例如
InnoDB
)的表,且交易隔離層級不是SERIALIZABLE
,則有可能當一個交易提交時,另一個正在進行中使用相同表的交易只會看到第一個交易的部分變更。也就是說,不能保證混合引擎的交易的原子性,且可能導致不一致。(如果混合引擎交易不頻繁,您可以視需要使用SET TRANSACTION ISOLATION LEVEL
,將每個交易的隔離層級設定為SERIALIZABLE
。)如果您在交易中使用非交易安全的表,則對這些表所做的變更會立即儲存,無論自動提交模式的狀態為何。
如果您在交易中更新非交易表之後發出
ROLLBACK
陳述式,則會發生ER_WARNING_NOT_COMPLETE_ROLLBACK
警告。對交易安全表所做的變更會被回滾,但對非交易安全表所做的變更則不會。
每個交易都會在 COMMIT
時以一個區塊儲存在二進位記錄中。已回滾的交易不會被記錄。(例外:無法回滾對非交易表所做的修改。如果回滾的交易包含對非交易表的修改,則整個交易會以結尾的 ROLLBACK
陳述式記錄下來,以確保將非交易表的修改複製。)請參閱第 7.4.4 節〈二進位記錄〉。
您可以使用 SET TRANSACTION
陳述式變更交易的隔離層級或存取模式。請參閱第 15.3.7 節〈SET TRANSACTION 陳述式〉。
回滾可能是一個緩慢的操作,它可能會在使用者沒有明確要求的情況下隱式發生(例如,當發生錯誤時)。因此,SHOW PROCESSLIST
在連線的 State
欄位中會顯示 Rolling back
,不僅對於使用 ROLLBACK
語句執行的明確回滾,也適用於隱式回滾。
在 MySQL 9.0 中,BEGIN
、COMMIT
和 ROLLBACK
不受 --replicate-do-db
或 --replicate-ignore-db
規則的影響。
當 InnoDB
執行一個交易的完整回滾時,該交易設定的所有鎖定都會被釋放。如果一個交易中的單一 SQL 語句因為錯誤而回滾,例如重複鍵錯誤,則該語句設定的鎖定會被保留,而交易保持活動狀態。這是因為 InnoDB
以一種格式儲存列鎖定,使其事後無法知道哪個鎖定是由哪個語句設定的。
如果交易中的 SELECT
語句呼叫一個預存函數,而該預存函數中的語句失敗,則該語句會回滾。如果隨後為該交易執行 ROLLBACK
,則整個交易將回滾。