iT邦幫忙

2023 iThome 鐵人賽

DAY 7
1
自我挑戰組

Techschool Goalng Backend Master Class 的學習記錄系列 第 7

[Day 07] A clean way to implement database transaction in Golang Part 1

  • 分享至 

  • xImage
  •  

What is a Database Transaction ?

  • A single unit of work
  • Often made up of multiple db operations
  • 只有兩種執行結果:全部執行成功 or 全部不執行(只要其中一個行為失敗就全部回滾)

https://ithelp.ithome.com.tw/upload/images/20230922/20121746jXBW2gntjn.png

Why do we need Database Transaction?

  1. 提供unit of work即使在系統故障是可靠且一致的
  2. 在同時存取database時提供隔離性,且保不會互相影響。

ACID

為了滿足上述的2個目標Database Transaction需要滿足ACID Property:

https://ithelp.ithome.com.tw/upload/images/20230922/20121746itaUnuN6yp.png

當我們談論資料庫的ACID,我們是在描述一組保證資料庫交易正確和可靠的屬性。ACID代表原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)和持久性(Durability),這四大特性確保了資料庫交易的可靠性和資料的安全性:

  • 原子性(Atomicity)
    • 把整個交易視為一個原子,是一個不可分割的邏輯單位
      所以要嘛整個交易成功,不然就是整個交易失敗,沒有存在成功一半,因此只要其中一個操作沒有完全,那就會rollback回到原本的狀態。
    • 範例:想像你在ATM提款機提現。這包括兩步:扣除你的帳戶餘額,和出錢。原子性保證這兩步要麼一起完成,要麼一步都不完成。
  • Consistency
    • 交易前後保持一致性,資料庫從一個有效狀態經過交易之後變成另一個有效狀態:
      • 寫入資料庫的所有數據必須是有效的
      • 交易進行後 資料庫的完整性沒有被破壞
    • 範例:如果銀行帳戶不允許餘額低於0,則交易不應該使餘額低於這個數值。
  • Isolation
    • Transaction過程中不會被其他Transaction影響
      他實際的效果會根據設定的isolation level 而有不同效果,但基本是要確保每個Transaction在進行時是互不干擾的
    • 範例:如果兩人同時從同一帳戶轉賬,每個人都看不到對方的交易,直到各自的交易完成。
  • Durability
    • 所有的數據都是由成功的Transaction交易寫入的,即使系統故障也不會丟失。
    • 範例:當你存錢後,即使銀行系統突然關機,你的存款資料也不會丟失。

How to Run SQL Transaction ?

https://ithelp.ithome.com.tw/upload/images/20230922/20121746ZmECWu40wH.png

BEGIN;

SQL queries;

...
COMMIT;
BEGIN;

SQL queries

...
ROLLBACK;

Transaction Isolation Level

Database必需滿足ACID的屬性,其中Isolation是四個屬性之一,其在最高Level的情況下會確保所有的Transaction不會相互影響。

Read Phenomena

同時運行其他Transaction 下有幾種方法可以產生干擾,而這干擾就稱為Read Phenomena:

Dirty Read

如果一個 transaction 還沒有 commit,但是你卻讀得到已經更新的結果,這個情形叫做 Dirty Read

Non-Repeatable Read

如果你在同一個 transaction 裡面連續使用相同的 Query 讀取了多次資料,但是相同的 Query 卻回傳了不同的結果,這個現象稱為 Non-repeatable reads

Phantom Read

當在同一個 transaction 連續兩次讀取時,讀取出來的筆數跟上次不同,這個情況稱為 Phantom reads

Serialization Anomaly

在成功提交一群交易後,結果與以所有可能的順序依序執行交易的結果都不一致

Isolation Levels

ANSI其定義SQL不同的 Isolation 等級來標明哪個等級的 Isolation 可以解決上述問題:

  • Read Uncommitted: 代表 transaction 可以讀到別的 transaction 尚未 commit 的資料,在這個等級中三個問題都沒有解決。
  • Read Committed: 代表 transaction 只能讀到別的 transaction 已經 commit 的資料,沒有 commit 的話就不會讀到,在這個等級解決了 Dirty Read 的問題。
  • Repeatable Read: 代表每次 transaction 要讀取特定欄位的資料時,只要 query 條件相同,讀取到的資料就會相同。在這個等級解決了 Non-repeatable reads 的問題。
  • Serializable: 代表在多個 transaction 同時執行時,只要 transaction 的順序相同時,得到的結果一定相同。比如說 Transaction A 先執行了接下來再執行 Transaction B,在同樣的條件下,每次執行都會得到一樣的結果。在這個等級下連同 Phantom reads 也會一併被解決。

https://ithelp.ithome.com.tw/upload/images/20230922/201217465IK5RWPwv9.png

https://ithelp.ithome.com.tw/upload/images/20230922/20121746QhyAn41HoC.png

Reference


上一篇
[Day 06] Write Unit Testing for Database (postgresSQL) CRUD
下一篇
[Day 08] A clean way to implement database transaction in Golang Part 2
系列文
Techschool Goalng Backend Master Class 的學習記錄31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言