儲存點是一種建立交易的方法,類似於 BEGIN 和 COMMIT,但不同的是,儲存點和釋放指令有名稱,而且可以巢狀。
儲存點指令會以一個名稱開始一個新的交易。交易名稱不需要是唯一的。儲存點可以在 BEGIN...COMMIT 內或外開始。當儲存點是最外層儲存點,而且不在 BEGIN...COMMIT 內時,行為會與 BEGIN DEFERRED TRANSACTION 相同。
ROLLBACK TO 指令會將資料庫狀態還原到對應儲存點之後的狀態。請注意,與一般 ROLLBACK 指令(沒有 TO 關鍵字)不同,ROLLBACK TO 指令不會取消交易。ROLLBACK TO 指令不會取消交易,而是會在開頭重新開始交易。不過,所有介於其中的儲存點都會被取消。
RELEASE 指令就像 COMMIT 對於 SAVEPOINT。RELEASE 指令會導致所有儲存點回到並包含與交易堆疊中具有相符名稱的最新儲存點。內部交易的 RELEASE 不會導致任何變更寫入資料庫檔案;它只是從交易堆疊中移除儲存點,使得無法再 ROLLBACK TO 這些儲存點。如果 RELEASE 指令釋放最外層儲存點,使得交易堆疊變為空,則 RELEASE 與 COMMIT 相同。COMMIT 指令可用於釋放所有儲存點並提交交易,即使交易最初是由 SAVEPOINT 指令而非 BEGIN 指令啟動。
如果 RELEASE 指令中的儲存點名稱與交易堆疊中目前任何儲存點不符,則不會釋放任何儲存點,資料庫保持不變,且 RELEASE 指令會傳回錯誤。
請注意,內部交易可能會提交(使用 RELEASE 指令),但稍後可能會因外部交易中的 ROLLBACK 而復原其工作。電源故障或程式崩潰或作業系統崩潰將導致最外層交易回滾,復原該外部交易中發生所有變更,即使是已假設已由 RELEASE 指令「提交」的變更。內容實際上並未提交到磁碟,直到最外層交易提交為止。
有幾種思考 RELEASE 指令的方式
有些人將 RELEASE 視為 SAVEPOINT 的 COMMIT 等效項。只要記得內部交易提交的變更稍後可能會因外部交易中的回滾而復原,這是一個可以接受的觀點。
RELEASE 的另一個觀點是,它將一個命名交易合併到其父交易中,因此命名交易及其父交易會變成同一個交易。在 RELEASE 之後,命名交易及其父交易將會一起提交或回滾,無論它們的命運如何。
也可以將儲存點視為交易時間軸中的「標記」。在這個觀點中,SAVEPOINT 指令會建立一個新的標記,ROLLBACK TO 指令會將時間軸倒轉到命名標記後的一個點,而 RELEASE 指令會從時間軸中刪除標記,而不會實際對資料庫進行任何變更。
最後開始的交易將會是第一個提交或回滾的交易。
只有在交易堆疊為空時,BEGIN 指令才會運作,換句話說,就是沒有任何待處理的交易。如果在呼叫 BEGIN 指令時交易堆疊不為空,則指令會失敗並傳回錯誤。
COMMIT 指令會提交所有未完成的交易,並將交易堆疊清空。
RELEASE 指令會從交易堆疊中最新的新增開始,並向後釋放儲存點,直到釋放一個具有相符儲存點名稱的儲存點。先前的儲存點,即使具有相符的儲存點名稱,也不會改變。如果 RELEASE 指令導致交易堆疊變為空(如果 RELEASE 指令從堆疊中釋放最外層的交易),則交易會提交。
沒有 TO 子句的 ROLLBACK 指令會回滾所有交易,並將交易堆疊清空。
具有 TO 子句的 ROLLBACK 指令會向後回滾交易,直到具有相符名稱的最新的 SAVEPOINT。具有相符名稱的 SAVEPOINT 會留在交易堆疊中,但建立該 SAVEPOINT 之後發生的所有資料庫變更都會被回滾。如果 ROLLBACK TO 指令中的儲存點名稱與堆疊中的任何 SAVEPOINT 都不相符,則 ROLLBACK 指令會失敗並傳回錯誤,且資料庫狀態保持不變。
此頁面最後修改於 2022-01-08 05:02:57 UTC