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 表( ),數據內容如下:

runoobdb# 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 命令裁撤所有的更改。

runoobdb=# 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 命令提交所有的更改。

runoobdb=# 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)