資料庫 Transaction(交易)

👀 4 min read 👀

大家好,我是 Cindy,非資訊科系相關背景的工程師,對於資料庫始終有許多的不理解,今天想跟大家分享我在網路上找到適合非本科系的同學們看的資料,以及分享一些我對於資料庫 Ttansaction 的理解。

網路上的相關資料

  • 資料庫系統管理課程
    關於資料庫 Transaction(交易) 可以看 Course 8. 交易處理Course 9. 並行控制與回復,裡面有 杰哥數位教室 youtube 課程可以搭配講義學習,雖然 youtube 音質不是很好,但整體看下來對於沒有上過資料庫課程的工程師,我覺得對於觀念的理解會蠻有幫助的。

  • MySQL 文件

  • PostgreSQL 文件

  • PostgreSQL 文件 - isolation
    MySQL 和 PostgreSQL 算是目前常用到的資料庫系統,如果在實務上有需要了解的時候,直接看文件會最快,因為各個資料庫系統實作的演算法不同。

什麼是 Transaction

如果有這樣的情境:某個功能需要對資料庫進行操作,且是對一或多筆資料進行操作,如果中間發生失敗,是不會允許有些資料變更成功,有些資料變更失敗的話,就會需要 Transaction。

MySQL 關於 Transaction 的描述

Transactions are atomic units of work that can be committed or rolled back. When a transaction makes multiple changes to the database, either all the changes succeed when the transaction is committed, or all the changes are undone when the transaction is rolled back.

Database transactions, as implemented by InnoDB, have properties that are collectively known by the acronym ACID, for atomicity, consistency, isolation, and durability.

See Also ACID, commit, isolation level, lock, rollback.

PostgreSQL 關於 Transaction 的描述

Transactions are a fundamental concept of all database systems. The essential point of a transaction is that it bundles multiple steps into a single, all-or-nothing operation. The intermediate states between the steps are not visible to other concurrent transactions, and if some failure occurs that prevents the transaction from completing, then none of the steps affect the database at all.

由以上內容可以看到關鍵字 committed or rolled back ,表示的是 Transaction 的兩種情況:

  • 成功:committed
  • 失敗:rolled back

其實也就是 all-or-nothing 的表示,要不是全部成功(all)就是全部失敗(nothing)。
最常見的例子就是轉帳,假如小明要轉帳給小美,我們不會希望有轉一半的情況發生,例如小明成功扣了轉帳出去的錢,而小美卻沒有得到小明轉進帳戶的錢,所以我們就會需要 Transaction 來幫助我們做到 all-or-nothing
=> 詳細參考資料:交易管理

Transaction 的四大特性 ACID

  • 單元性 (Atomicity;基元性):
    • 交易是一個不可再分割的完整個體,它不是全部執行,就是全部不執行。
    • 確保單元性是回復 (Recovery) 的責任。
  • 一致性 (Consistency):
    • 如果交易是全部執行,能讓資料庫從某個一致狀態,轉變到另一個一致狀態。我們則稱此次交易具有一致性。
    • 確保一致性通常是 DBMS 程式設計師的責任。
  • 孤立性 (Isolation):
    • 某交易執行期間所用的資料或中間結果,不容許其它交易讀取或寫入,直到此交易被確認 (Commit,即:成功結束) 為止。也就是說,它不應被同時執行的其它交易所干擾。
    • 確保孤立性是並行控制 (Concurrency Control) 的責任。可依需求定立不同層級的限制。
  • 永久性 (Durability, Permanency):
    • 一旦交易全部執行,且經過確認 (Commit) 後,其對資料庫所做的變更則永遠有效,即使未來系統當機或毀損。
    • 一般是以備份(Back Up)、硬碟映射(Disk Mirroring)、系統日誌(System Log、System Journal)等數種方式來達成。
    • 永久性是回復 (Recovery) 的責任。

由上面敘述就可以知道,實現 Transaction 最重要的兩件事情就是:

  1. 失敗回復、復原 (Failure Recovery)
  2. 並行控制 (Concurrency Control)
    => 詳細參考資料:並行控制與回復

SQL 標準中定義了四種數據庫的隔離級別

圖片來自 PostgreSQL 文件

  • RAED UNCOMMITED:使用查詢語句不會加鎖,可能會讀到未提交的資料(Dirty Read)
  • READ COMMITED:只對記錄加記錄鎖,而不會在記錄之間加間隙鎖,所以允許新的記錄插入到被鎖定記錄的附近,所以再多次使用查詢語句時,可能得到不同的結果(Non-Repeatable Read)
  • REPEATABLE READ:多次讀取同一範圍的數據會返回第一次查詢的快照,不會返回不同的數據行,但是可能發生幻讀(Phantom Read)
  • SERIALIZABLE:InnoDB 隱式地將全部的查詢語句加上共享鎖,解決了幻讀的問題

p.s. MySQL 的 InnoDB 預設的是 Repeatable Read
p.s. PostgreSQL 預設的是 Read Committed

其他可參考資料: