除非在交易中,否則不會讀取或寫入。任何存取資料庫的指令(基本上是任何 SQL 指令,除了少數 PRAGMA 陳述式)如果尚未生效,將自動開始交易。自動開始的交易會在最後一個 SQL 陳述式結束時提交。
交易可以使用 BEGIN 指令手動開始。此類交易通常會持續到下一個 COMMIT 或 ROLLBACK 指令。但如果資料庫關閉或發生錯誤且指定 ROLLBACK 衝突解決演算法,交易也會 ROLLBACK。請參閱 ON CONFLICT 子句的文件,以取得有關 ROLLBACK 衝突解決演算法的其他資訊。
END TRANSACTION 是 COMMIT 的別名。
使用 BEGIN...COMMIT 建立的交易不會巢狀。對於巢狀交易,請使用 SAVEPOINT 和 RELEASE 指令。語法圖表上方所示 ROLLBACK 指令的「TO SAVEPOINT name」子句僅適用於 SAVEPOINT 交易。嘗試在交易中呼叫 BEGIN 指令會失敗並產生錯誤,無論交易是由 SAVEPOINT 或先前的 BEGIN 開始的。COMMIT 指令和沒有 TO 子句的 ROLLBACK 指令對 SAVEPOINT 交易的工作方式與由 BEGIN 開始的交易相同。
SQLite 支援來自不同資料庫連線(可能在不同的執行緒或程序中)的多個同時讀取交易,但僅支援一個同時寫入交易。
讀取交易用於僅讀取。寫入交易允許讀取和寫入。讀取交易由 SELECT 陳述式開始,而寫入交易由 CREATE、DELETE、DROP、INSERT 或 UPDATE 等陳述式開始(統稱為「寫入陳述式」)。如果在讀取交易處於活動狀態時發生寫入陳述式,則會在可能的情況下將讀取交易升級為寫入交易。如果其他資料庫連線已修改資料庫或已在修改資料庫的過程中,則無法升級為寫入交易,且寫入陳述式會失敗,並出現 SQLITE_BUSY。
在讀取交易處於活動狀態時,由個別資料庫連線執行的任何資料庫變更,都不會被啟動讀取交易的資料庫連線看到。如果資料庫連線 X 持有讀取交易,則其他資料庫連線 Y 可能在 X 的交易仍開啟時變更資料庫的內容,但 X 在交易結束之前都無法看到這些變更。在讀取交易處於活動狀態時,X 將持續看到 Y 執行的變更之前的資料庫歷史快照。
交易可以是延遲、立即或獨佔。交易的預設行為是延遲。
延遲表示交易並未實際開始,直到首次存取資料庫為止。在內部,BEGIN DEFERRED 陳述式僅設定資料庫連線上的旗標,關閉最後一個陳述式完成時通常會發生的自動提交。這會導致自動啟動的交易持續存在,直到明確的 COMMIT 或 ROLLBACK,或因錯誤或 ON CONFLICT ROLLBACK 子句而引發回滾為止。如果 BEGIN DEFERRED 之後的第一個陳述式是 SELECT,則會啟動讀取交易。後續寫入陳述式會在可能的情況下將交易升級為寫入交易,或傳回 SQLITE_BUSY。如果 BEGIN DEFERRED 之後的第一個陳述式是寫入陳述式,則會啟動寫入交易。
IMMEDIATE 會導致資料庫連線立即開始新的寫入,而不等待寫入陳述式。如果另一個寫入交易已在另一個資料庫連線中執行中,BEGIN IMMEDIATE 可能會失敗並傳回 SQLITE_BUSY。
EXCLUSIVE 與 IMMEDIATE 類似,因為寫入交易會立即開始。在 WAL 模式 中,EXCLUSIVE 與 IMMEDIATE 相同,但在其他記錄模式中,EXCLUSIVE 會防止其他資料庫連線在交易進行中讀取資料庫。
隱式交易(自動開始的交易,而非由 BEGIN 開始的交易)會在最後一個活動陳述式完成時自動提交。陳述式會在其最後一個游標關閉時完成,這會在準備好的陳述式 重設 或 完成 時發生。有些陳述式可能會在重設或完成之前「完成」交易控制,但無法保證這一點。確保陳述式已「完成」的唯一方法是對該陳述式呼叫 sqlite3_reset() 或 sqlite3_finalize()。用於漸增 BLOB I/O 的開啟 sqlite3_blob 也會計為未完成的陳述式。sqlite3_blob 會在 關閉 時完成。
明確的 COMMIT 命令會立即執行,即使有待處理的 SELECT 陳述式。但是,如果存在待處理的寫入操作,COMMIT 命令會失敗並傳回錯誤碼 SQLITE_BUSY。
如果另一個執行緒或處理程序有開啟的讀取連線,嘗試執行 COMMIT 也可能會導致 SQLITE_BUSY 回傳碼。當 COMMIT 以這種方式失敗時,交易仍保持活動狀態,並且可以在讀取器有機會清除後稍後重試 COMMIT。
在非常舊版本的 SQLite 中(3.7.11 版本之前 - 2012-03-20),如果存在任何待處理查詢,則 ROLLBACK 會失敗並顯示錯誤代碼 SQLITE_BUSY。在較新的 SQLite 版本中,ROLLBACK 會繼續執行,而待處理陳述式通常會中斷,導致它們傳回 SQLITE_ABORT 或 SQLITE_ABORT_ROLLBACK 錯誤。在 SQLite 3.8.8 版本(2015-01-16)和更新版本中,只要 ROLLBACK 未修改資料庫架構,待處理讀取就會在 ROLLBACK 之後繼續運作。
如果 PRAGMA journal_mode 設為 OFF(因此停用回滾日誌檔案),則 ROLLBACK 命令的行為未定義。
如果交易中發生某些類型的錯誤,則交易可能會自動回滾或不會自動回滾。可能導致自動回滾的錯誤包括
對於所有這些錯誤,SQLite 會嘗試只復原它正在處理的那一個陳述式,並讓同一個交易中先前陳述式的變更保持完整並繼續進行交易。但是,根據正在評估的陳述式和錯誤發生的時間點,SQLite 可能需要回滾並取消整個交易。應用程式可以使用 sqlite3_get_autocommit() C 語言介面來判斷 SQLite 採取哪種行動。
建議應用程式透過明確發出 ROLLBACK 命令來回應上述錯誤。如果交易已因錯誤回應而自動回滾,則 ROLLBACK 命令會失敗並顯示錯誤,但這不會造成任何損害。
未來版本的 SQLite 可能會擴充可能導致自動交易回滾的錯誤清單。未來版本的 SQLite 可能會變更錯誤回應。特別是,我們可能會在未來版本的 SQLite 中簡化介面,讓上述錯誤強制執行無條件回滾。
此頁面最後修改於 2023-03-14 14:31:07 UTC