事務、特性、隔離級別

MaChao發表於2020-10-30

什麼是事務

  • 事務是指程式中一系列嚴密的邏輯操作,而且所有操作必須全部完成,否則在每個操作中所做的所有更改都會被撤銷。
  • 換言之:就是把多件事情當做一件事情來處理,好比大家同在一條船上,要活一起活,要完一起完。

事務的四個特性

  • 原子性[atomicity]
  • 一致性[consistency]
  • 隔離性[isolation]
  • 永續性[durability]

資料事務的隔離級別

事務的隔離級別有4種,由低到高分別為Read uncommitted、Read committed、Repeatable read、Serializable。而且,在事務的併發操作中可能出現髒讀、不可重複讀、幻讀。

Read uncommitted 最低階別,任何情況都無法保證。

老闆要給程式設計師發工資,程式設計師的工資是3.6/月。但是發工資時老闆不小心按錯了數字,按成3.9/月,該錢已經打到程式設計師的戶口,但是事務還沒有提交,就在這時,程式設計師去檢視自己這個月的工資,發現比往常多了3千元,以為漲工資了非常高興。但是老闆及時發現了不對,馬上回滾差點就提交了的事務,將數字改成3.6萬再提交。

實際程式設計師這個月的工資還是3.6萬,但是程式設計師看到的是3.9萬。他看到的是老闆還沒提交事務時的資料。這就是髒讀。

Read committed 可避免髒讀的發生。

程式設計師拿著信用卡去享受生活(卡里當然是只有3.6萬),當他埋單時(程式設計師事務開啟),收費系統事先檢測到他的卡里有3.6萬,就在這個時候!!程式設計師的妻子要把錢全部轉出充當家用,並提交。當收費系統準備扣款時,再檢測卡里的金額,發現已經沒錢了(第二次檢測金額當然要等待妻子轉出金額事務提交完)。程式設計師就會很鬱悶,明明卡里是有錢的…

這就是讀提交,若有事務對資料進行更新(UPDATE)操作時,讀操作事務要等待這個更新操作事務提交後才能讀取資料,可以解決髒讀問題。但在這個事例中,出現了一個事務範圍內兩個相同的查詢卻返回了不同資料,這就是不可重複讀。

Repeatable read 可避免髒讀、不可重複讀的發生。

程式設計師拿著信用卡去享受生活(卡里當然是只有3.6萬),當他埋單時(事務開啟,不允許其他事務的UPDATE修改操作),收費系統事先檢測到他的卡里有3.6萬。這個時候他的妻子不能轉出金額了。接下來收費系統就可以扣款了。

重複讀可以解決不可重複讀問題。寫到這裡,應該明白的一點就是,不可重複讀對應的是修改,即UPDATE操作。但是可能還會有幻讀問題。因為幻讀問題對應的是插入INSERT操作,而不是UPDATE操作。
什麼時候會出現幻讀?

程式設計師某一天去消費,花了2千元,然後他的妻子去檢視他今天的消費記錄(全表掃描FTS,妻子事務開啟),看到確實是花了2千元,就在這個時候,程式設計師花了1萬買了一部電腦,即新增INSERT了一條消費記錄,並提交。當妻子列印程式設計師的消費記錄清單時(妻子事務提交),發現花了1.2萬元,似乎出現了幻覺,這就是幻讀。

Serializable 可避免髒讀、不可重複讀、幻讀的發生。Mysql的預設隔離級別是Repeatable read。

事物併發導致的問題

在許多事物處理同一個資料時,如果沒有采取有效的隔離機制,那麼併發處理資料時,會帶來一些問題。

第一類丟失更新:撤銷一個事務時,把其他事務已提交的更新資料覆蓋。

小明去銀行櫃檯存錢,他的賬戶裡原來的餘額為100元,現在打算存入100元。在他存錢的過程中,銀行年費扣了5元,餘額只剩95元。突然他又想著這100元要用來請女朋友看電影吃飯,不打算存了。在他撤回存錢操作後,餘額依然為他存錢之前的100元。所以那5塊錢到底扣了誰的?

髒讀 一個事務處理過程中讀取了另一個未提交的事物中的資料。

小明的銀行卡餘額裡有100元。現在他打算用手機點一個外賣飲料,需要付款10元。但是這個時候,他的女朋友看中了一件衣服95元,她正在使用小明的銀行卡付款。於是小明在付款的時候,程式後臺讀取到他的餘額只有5塊錢了,根本不夠10元,所以系統拒絕了他的交易,告訴餘額不足。但是小明的女朋友最後因為密碼錯誤,無法進行交易。小明非常鬱悶,明明銀行卡里還有100元,怎麼會餘額不足呢?(他女朋友更鬱悶。。。)

幻讀又稱虛讀 一個事務執行兩次查詢,第二次結果集包含第一次中沒有或某些行已經被刪除的資料,造成兩次結果不一致,只是另一個事務在這兩次查詢中間插入或刪除了資料造成的。
不可重複讀 一個事務兩次讀取同一行的資料,結果得到不同狀態的結果,中間正好另一個事務更新了該資料,兩次結果相異,不可被信任。

例如事務T1對一個表中所有的行的某個資料項做了從“1”修改為“2”的操作,這時事務T2又對這個表中插入了一行資料項,而這個資料項的數值還是為“1”並且提交給資料庫。而操作事務T1的使用者如果再檢視剛剛修改的資料,會發現還有一行沒有修改,其實這行是從事務T2中新增的,就好像產生幻覺一樣,這就是發生了幻讀。

不可重複讀 一個事務兩次讀取同一行的資料,結果得到不同狀態的結果,中間正好另一個事務更新了該資料,兩次結果相異,不可被信任。

例如事務T1在讀取某一資料,而事務T2立馬修改了這個資料並且提交事務給資料庫,事務T1再次讀取該資料就得到了不同的結果,傳送了不可重複讀。
不可重複讀和髒讀的區別:髒讀是某一事務讀取了另一個事務未提交的髒資料,而不可重複讀則是讀取了前一事務提交的資料。 
幻讀和不可重複讀都是讀取了另一條已經提交的事務(這點就髒讀不同),所不同的是不可重複讀查詢的都是同一個資料項,而幻讀針對的是一批資料整體(比如資料的個數)。

第二類丟失更新:是不可重複讀的特殊情況。
如果兩個事務都讀取同一行,然後兩個都進行寫操作,並提交,第一個事務所做的就會丟失。

小明和女朋友一起去逛街。女朋友看中了一支口紅,(對,女朋友就是用來表現買買買的)小明大方的掏出了自己的銀行卡,告訴女朋友:親愛的,隨便刷,隨便買,我坐著等你。然後小明就坐在商城座椅上玩手機,等著女朋友。這個時候,程式設計師的聊天群裡有人推薦了一本書,小明一看,哎呀,真是本好書,還是限量發行呢,我一定更要買到。於是小明趕緊找到購買渠道,進行付款操作。而同時,小明的女朋友也在不亦樂乎的買買買,他們同時進行了一筆交易操作,但是這個時候銀行系統出了問題,當他們都付款成功後,卻發現,銀行只扣了小明的買書錢,卻沒有扣去女朋友此時交易的錢。哈哈哈,小明真是太開心了!

英文

  • transation 事務
  • atomicity 原子性
  • consistency 一致性
  • isolation 隔離性
  • durability 永續性
  • read uncommitted 讀未提交
  • read committed 讀已提交
  • repeatable read 可重複讀
  • serializable 序列化

概念

名稱 解釋
原子性 是操作這些指令時,要麼全部執行成功,要麼全部不執行。只要其中一個指令執行失敗,所有的指令都執行失敗,資料進行回滾,回到執行指令前的資料狀態。
一致性 事物的執行使資料從一個狀態轉換為另一個狀態,但是對於整個資料的完整性保持穩定。
隔離性 隔離性是多個使用者併發訪問資料庫時,比如操作同一張表時,資料庫為每個使用者開啟的事務,不能被其他事務的操作所干擾,多個併發事物之間要相互隔離。對於任意兩個併發的事務t1和t2,在事物t1看來,t2要麼在t1開始之前就已經結束,要麼在t1結束之後才開始,這樣每個事物都感覺不到其他事務在併發地執行。
永續性 當事務正確完成後,他對於資料的改變時持久的。
讀未提交 最低階別,任何情況都無法保證。讀未提交,顧名思義,就是一個事務可以讀取另一個未提交事務的資料。
讀已提交 可避免髒讀的發生。讀提交,顧名思義,就是一個事務要等另一個事務提交後才能讀取資料。
可重複讀 可避免髒讀、不可重複讀的發生。重複讀,就是開始讀取資料時[事務開啟],不在允許修改操作。
序列化 可避免髒讀、不可重複讀、幻讀的發生。是最高的事務隔離級別,在該級別下,事務序列化順序執行,可避免髒讀、不可重複讀、幻讀。但是這樣事務隔離級別效率低下,比較耗資料庫效能,一般不使用。

相關文章

www.cnblogs.com/Kevin-ZhangCG/p/90...

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章