天天看點

事務解釋

前言

事務是我們保證資料正确性的重要手段,隻要和資料庫打交道,就得了解它的 ACID 特性,這也是一個專業程式員應該掌握的基本技能。

事務是什麼?

在資料庫的世界裡,我們最常打交道的是 SQL 操作語句。然而,SQL 語句并不是資料庫的最小處理機關,事務才是。

事務包含了一條或多條 SQL 語句。這些 SQL 語句會被視為一個任務集合,而事務就保證了這個任務集合裡的 SQL 要麼全部執行完,要麼都不執行,不會讓資料處于一個中間操作狀态。

事務解釋

資料庫是面向多線程多使用者設計的,同一時刻會被多個程式讀取或修改。在并發操作時,需要考慮對同一資源的通路控制。而事務在這方面有完善的處理機制,後面将會提及到事務的隔離性。

另外,事務能保證資料的完整性,這包括邏輯上的完整以及實體上的完整性。

邏輯上的完整性是指不會存在中間狀态的資料;隻會成功或失敗復原。

實體上的完整性是指事務隻要執行成功,那麼即使重新開機也不會丢失執行結果。(當然,前提是資料檔案沒有損壞......)

事務的使用

事務的整體流程主要涉及到幾個狀态點:

(1)開始事務:BEGIN TRANSACTION;

(2)送出事務:COMMIT;

(3)復原事務:ROLLBACK;

一般的,當我們在執行一條 SQL 語句時就已經預設幫我們開啟了事務。若執行成功,則會送出事務。若執行失敗,則會復原事務。

其中,送出事務後,相對應的資料也會被持久化到硬碟上,即時重新開機也不會丢失。

事務的 ACID

前面提到過,事務能保證資料的完整性,它主要是通過 ACID 特性來保證的:

1、原子性(Atomicity)

事務是一個不可分割的機關,是以在一個事務裡的所有操作要麼全部生效,要麼全部不生效。

2、一緻性(Consistency)

也可以了解為是預期狀态的正确性,即從一個正确的狀态到另一個正确的狀态,這裡的狀态往往是由業務來定義的。

比如轉賬中的一個扣錢一個加錢,是我們規定的一個資料流轉,那麼執行前的賬戶餘額和轉賬後的賬戶餘額就得滿足加減特性,這就是所謂的業務正确。

3、隔離性(Isolation)

資料庫是允許多個事務并發執行的,每個事務在執行時理想狀态是互不影響。然而要達到這個效果就得串行執行事務,這樣并發能力也會大大降低。

是以,為了兼顧執行效率,将互相影響的程度分為了 4 個隔離級别:

1)未送出讀:

舉個例子,當事務 A 對表 1 進行更新操作後,有事務 B 讀取了更新後的資料,後面又由于某種原因,事務 A 進行了復原。

這樣對于事務 B 來講就依賴了一個無效的復原資料,進而後面所做出的決策,也不一定正确了,這就是所謂的髒讀,也就是未送出讀隔離級别,此級别資料一緻性最差,但并發性最好。

2)已送出讀:

如果想防止髒讀,就需要等待其他事務送出後再進行讀取操作。防止了無效的復原情況,這就是已送出讀隔離級别。

3)可重複讀:

已送出讀的隔離級别考慮到了資料復原的無效性,卻無法阻止事務的多次送出。

比如事務 A 不斷的對表進行修改送出,那麼事務 B 就會在不同的時間點讀取到不同的資料。

為了讓事務 B 在執行期間讀取的資料都是一緻的,就有了可重複讀的隔離級别,即事務 B 在執行期間,其他事務不得進行修改操作。

4)可串行化:

上面的可重複讀隔離級别保證了事務執行期間讀取的一緻性。然而這裡并不包括插入、删除操作。

即會出現讀多讀少資料的情況,這種現象叫做幻讀。

為了解決幻讀,隻得進行串行化執行事務,才能互不影響。而此時的事務并發性是最低的。

4、持久化(Durability)

最後一個事務特性就是持久化性。通過日志等手段,隻要我們的事務送出成功了,那麼就意味着這次的資料操作是成功的。即使下次重新開機了程式,也不會丢失此處的操作結果!

總結

事務的 ACID 特性保證了資料的完整性。其中,事務的隔離級别越高,資料一緻性越好,但并發能力就越差。這是需要我們在實際開發中取舍的。像日志記錄的讀取,使用髒讀就對總體影響不大。