1. 程式人生 > 其它 >【資料庫】資料庫事務

【資料庫】資料庫事務

轉載地址:https://www.liaoxuefeng.com/wiki/1177760294764384/1179611198786848

事務是什麼?

【事務】:是使用者定義的一個數據庫操作序列,這些操作要麼都做,要麼都不做,是一個不可分割的工作單元 例如:

在執行SQL語句的時候,某些業務要求,一系列操作必須全部執行,而不能僅執行一部分。例如,一個轉賬操作:

-- 從id=1的賬戶給id=2的賬戶轉賬100元
-- 第一步:將id=1的A賬戶餘額減去100
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
-- 第二步:將id=2的B賬戶餘額加上100
UPDATE accounts SET balance = balance + 100 WHERE id = 2;

這兩條SQL語句必須全部執行,或者,由於某些原因,如果第一條語句成功,第二條語句失敗,就必須全部撤銷。

這種把多條語句作為一個整體進行操作的功能,被稱為資料庫事務。資料庫事務可以確保該事務範圍內的所有操作都可以全部成功或者全部失敗。如果事務失敗,那麼效果就和沒有執行這些SQL一樣,不會對資料庫資料有任何改動。

事務的基本特徵是什麼?

可見,資料庫事務具有ACID這4個特性:

  • A:Atomic,原子性,將所有SQL作為原子工作單元執行,要麼全部執行,要麼全部不執行;
  • C:Consistent,一致性,事務完成後,所有資料的狀態都是一致的,即A賬戶只要減去了100,B賬戶則必定加上了100;
  • I:Isolation,隔離性,如果有多個事務併發執行,每個事務作出的修改必須與其他事務隔離;
  • D:Duration,永續性,即事務完成後,對資料庫資料的修改被持久化儲存。

對於單條SQL語句,資料庫系統自動將其作為一個事務執行,這種事務被稱為隱式事務

要手動把多條SQL語句作為一個事務執行,使用BEGIN開啟一個事務,使用COMMIT提交一個事務,這種事務被稱為顯式事務,例如,把上述的轉賬操作作為一個顯式事務:

BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;

很顯然多條SQL語句要想作為一個事務執行,就必須使用顯式事務。

COMMIT是指提交事務,即試圖把事務內的所有SQL所做的修改永久儲存。如果COMMIT語句執行失敗了,整個事務也會失敗。

有些時候,我們希望主動讓事務失敗,這時,可以用ROLLBACK回滾事務,整個事務會失敗:

BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
ROLLBACK;

資料庫事務是由資料庫系統保證的,我們只需要根據業務邏輯使用它就可以。

隔離級別

對於兩個併發執行的事務,如果涉及到操作同一條記錄的時候,可能會發生問題。因為併發操作會帶來資料的不一致性,包括髒讀、不可重複讀、幻讀等。資料庫系統提供了隔離級別來讓我們有針對性地選擇事務的隔離級別,避免資料不一致的問題。

SQL標準定義了4種隔離級別,分別對應可能出現的資料不一致的情況:

Isolation Level髒讀(Dirty Read)不可重複讀(Non Repeatable Read)幻讀(Phantom Read)
Read Uncommitted Yes Yes Yes
Read Committed - Yes Yes
Repeatable Read - - Yes
Serializable - - -

我們會依次介紹4種隔離級別的資料一致性問題。

程式設計是個人愛好