PostgreSQL TRANSACTION(事務)
TRANSACTION(事務)是資料庫管理系統執行過程中的一個邏輯單位,由一個有限的資料庫操作序列構成。
資料庫事務通常包含了一個序列的對數據庫的讀/寫操作。包含有以下兩個目的:
- 為數據庫操作序列提供了一個從失敗中恢復到正常狀態的方法,同時提供了資料庫即使在異常狀態下仍能保持一致性的方法。
- 當多個應用程式在併發訪問資料庫時,可以在這些應用程式之間提供一個隔離方法,以防止彼此的操作互相干擾。
當事務被提交給了資料庫管理系統(DBMS),則 DBMS 需要確保該事務中的所有操作都成功完成且其結果被永久保存在資料庫中,如果事務中有的操作沒有成功完成,則事務中的所有操作都需要回滾,回到事務執行前的狀態;同時,該事務對數據庫或者其他事務的執行無影響,所有的事務都好像在獨立的運行。
事務的屬性
事務具有以下四個標準屬性,通常根據首字母縮寫為 ACID:
- 原子性(Atomicity):事務作為一個整體被執行,包含在其中的對數據庫的操作要麼全部被執行,要麼都不執行。
- 一致性(Consistency):事務應確保資料庫的狀態從一個一致狀態轉變為另一個一致狀態。一致狀態的含義是資料庫中的數據應滿足完整性約束。
- 隔離性(Isolation):多個事務併發執行時,一個事務的執行不應影響其他事務的執行。
- 持久性(Durability):已被提交的事務對數據庫的修改應該永久保存在資料庫中。
例子
某人要在商店使用電子貨幣購買100元的東西,當中至少包括兩個操作:
- 該人帳戶減少 100 元。
- 商店帳戶增加100元。
支持事務的資料庫管理系統就是要確保以上兩個操作(整個"事務")都能完成,或一起取消,否則就會出現 100 元平白消失或出現的情況。
事務控制
使用下麵的命令來控制事務:
- BEGIN TRANSACTION:開始一個事務。
- COMMIT:事務確認,或者可以使用 END TRANSACTION 命令。
- ROLLBACK:事務回滾。
事務控制命令只與 INSERT、UPDATE 和 DELETE 一起使用。他們不能在創建表或刪除表時使用,因為這些操作在資料庫中是自動提交的。
BEGIN TRANSACTION 命令
事務可以使用 BEGIN TRANSACTION 命令或簡單的 BEGIN 命令來啟動。此類事務通常會持續執行下去,直到遇到下一個 COMMIT 或 ROLLBACK 命令。不過在資料庫關閉或發生錯誤時,事務處理也會回滾。以下是啟動一個事務的簡單語法:
BEGIN; 或者 BEGIN TRANSACTION;
COMMIT 命令
COMMIT 命令是用於把事務調用的更改保存到資料庫中的事務命令,即確認事務。
COMMIT 命令的語法如下:
COMMIT; 或者 END TRANSACTION;
ROLLBACK 命令
ROLLBACK 命令是用於撤銷尚未保存到資料庫的事務命令,即回滾事務。
ROLLBACK 命令的語法如下:
ROLLBACK;
實例
創建 COMPANY 表(下載 COMPANY SQL 檔 ),數據內容如下:
zaixiandb# select * from COMPANY; id | name | age | address | salary ----+-------+-----+-----------+-------- 1 | Paul | 32 | California| 20000 2 | Allen | 25 | Texas | 15000 3 | Teddy | 23 | Norway | 20000 4 | Mark | 25 | Rich-Mond | 65000 5 | David | 27 | Texas | 85000 6 | Kim | 22 | South-Hall| 45000 7 | James | 24 | Houston | 10000 (7 rows)
現在,讓我們開始一個事務,並從表中刪除 age = 25 的記錄,最後,我們使用 ROLLBACK 命令撤銷所有的更改。
zaixiandb=# BEGIN; DELETE FROM COMPANY WHERE AGE = 25; ROLLBACK;
檢查 COMPANY 表,仍然有以下記錄:
id | name | age | address | salary ----+-------+-----+-----------+-------- 1 | Paul | 32 | California| 20000 2 | Allen | 25 | Texas | 15000 3 | Teddy | 23 | Norway | 20000 4 | Mark | 25 | Rich-Mond | 65000 5 | David | 27 | Texas | 85000 6 | Kim | 22 | South-Hall| 45000 7 | James | 24 | Houston | 10000
現在,讓我們開始另一個事務,從表中刪除 age = 25 的記錄,最後我們使用 COMMIT 命令提交所有的更改。
zaixiandb=# BEGIN; DELETE FROM COMPANY WHERE AGE = 25; COMMIT;
檢查 COMPANY 表,記錄已被刪除:
id | name | age | address | salary ----+-------+-----+------------+-------- 1 | Paul | 32 | California | 20000 3 | Teddy | 23 | Norway | 20000 5 | David | 27 | Texas | 85000 6 | Kim | 22 | South-Hall | 45000 7 | James | 24 | Houston | 10000 (5 rows)