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 8.4 中,BEGIN
、COMMIT
和 ROLLBACK
不會受到 --replicate-do-db
或 --replicate-ignore-db
規則的影響。
當 InnoDB
執行交易的完整復原時,會釋放交易設定的所有鎖定。如果交易中的單一 SQL 陳述式因錯誤 (例如重複的索引鍵錯誤) 而復原,則在交易保持作用中時,陳述式設定的鎖定會保留。發生這種情況是因為 InnoDB
儲存資料列鎖定的格式使其無法事後知道哪個鎖定是由哪個陳述式設定的。
如果交易中的 SELECT
陳述式呼叫了預存函式,且預存函式中的陳述式失敗,則該陳述式會回滾。如果後續對交易執行 ROLLBACK
,則整個交易會回滾。