iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 19
0
Modern Web

前端工程師一起來種一棵後端技能樹吧!系列 第 19

[Day 19] Transaction 併發錯誤與隔離層級 - (2)

上一篇文章提到併發狀態的 transaction 仍然會遇到一些不預期的錯誤,分別有髒讀、不可重複讀、幻讀,今天就要來看看資料庫是怎麼解決這些問題的。

解決併發事務一致性難題:隔離層級

其實當你第一次思考這個問題的時候,你心中可能會想到一個解法

那不然…不要併發執行…序列化執行就沒事了…?

這個觀念是對的,它的確可以解決資料不一致的問題,然而這樣的一致性卻是用效能換來的,當你遇到高流量的狀況,這樣系統很可能會直接掛掉的,因此最好的方式是因應不同的情況,在 效能 與 一致性 間做一個權衡取捨,也就是這裡要介紹的隔離層級。

上圖就是今天要介紹的四種隔離層級,最上面的 read uncommitted 效能最好,但一致性最差,到了最下面的 serializable,變成一致性最好,但效能最差。

Read Uncommitted

這是最低的隔離層級,SELECT 指令可以讀取其他 transaction 尚未 commit 的結果,如果這個尚未被 commit 的結果後來被 rollback 了,就會讀取到被取消的資料,也就是剛剛提過的「髒讀」。不過 UPDATE 等「寫」的操作是不會成功的。

這種隔離層級可能產生:

  • 髒讀
  • 不可重複讀
  • 幻讀

Read Committed

這個隔離層級只允許讀取其他 transaction commit 過的資料,因此可以解決髒讀的問題,不過如果一個 transaction 的兩個 SELECT 語法間有另一個交易 commit 了新資料,會造成第一次讀取與第二次讀取結果不一致的問題,也就是上面介紹過的不可重複讀。

這種隔離層級可能產生:

  • 不可重複讀
  • 幻讀

Repeatable Read

此種隔離層級為 innodb 預設的隔離層級,不會考慮別的 transaction 的修改,同一個 transaction 內,除非自己修改,否則多次 SELECT 的結果都會相同,解決了不可重複讀的問題。

這種隔離層級可能產生:

  • 幻讀

Serializable

在一開始提過,是一個用效能換取一致性的隔離層級,讓所有 transaction 序列化執行,避免併發可能會造成的問題。

Deadlock 死結

小結

這篇文簡單介紹了併發的 transaction 可能會發生的三種問題與它的解法 —四種隔離層級,你可能會好奇隔離層級又是怎麼做到的?其實隔離層級背後運用了一個概念:鎖(Lock),如果對這部分有興趣的讀者再自行研究囉。

Medium 版本連結

https://medium.com/@oldmo860617/transaction-%E4%BD%B5%E7%99%BC%E9%8C%AF%E8%AA%A4%E8%88%87%E9%9A%94%E9%9B%A2%E5%B1%A4%E7%B4%9A-51b8af6178ae


上一篇
[Day 18] Transaction 併發錯誤與隔離層級 - (1)
下一篇
[Day 20] 初步認識分散式資料庫與 NoSQL CAP 理論 - (1)
系列文
前端工程師一起來種一棵後端技能樹吧!30

尚未有邦友留言

立即登入留言