搞懂什么是数据库事务
目錄前言事務(wù)的定義事務(wù)中的四大特性:ACID小案例ACID原子性一致性隔離性持久性回到案例實(shí)現(xiàn)原理并發(fā)控制日志恢復(fù)事務(wù)的隔離級別一次封鎖鎖/兩段鎖四種隔離級別前置概念臟讀不可重復(fù)讀幻讀隔離級別總結(jié)
前言
事務(wù)(Transaction)是數(shù)據(jù)庫學(xué)習(xí)中非常重要的一種概念,作為關(guān)系型數(shù)據(jù)庫的核心組成,在數(shù)據(jù)安全方面有著非常重要的作用。
事務(wù)在各大數(shù)據(jù)庫中都有非常廣泛的應(yīng)用,并且對于很多業(yè)務(wù),例如電商、支付,是保證其可以正常運(yùn)行的根基。
本文會(huì)逐步解析數(shù)據(jù)庫事務(wù)的核心特性,以獲得對事務(wù)更深的理解,主要以MySql的InnoDB引擎來講解。
希望對各位有所幫助,覺得不錯(cuò)可以給點(diǎn)個(gè)贊哦~
事務(wù)的定義
事務(wù)是一個(gè)數(shù)據(jù)庫操作序列,由事務(wù)開始與事務(wù)結(jié)束之間執(zhí)行的全部數(shù)據(jù)庫操作組成,這些操作要么全部執(zhí)行,要么全部不執(zhí)行,是一個(gè)不可分割的工作單位。
白話講就是,要么做完,要么別做,做一半了別想跑,你得給把爛攤子收好再走人!
事務(wù)中的四大特性:ACID
小案例
什么是ACID,即:原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability)
來看一個(gè)銀行轉(zhuǎn)賬的案例簡單體會(huì)一下,然后我們再來詳細(xì)解釋
小明用網(wǎng)銀給小紅轉(zhuǎn)賬100元,在這種交易的過程中,有幾個(gè)問題需要思考
A:如何同時(shí)保證,小明總金額減少100元,小紅總金額增加100元?
C:小明正在轉(zhuǎn)賬時(shí),小李用小明的卡在ATM提走了全部的錢,小明還能轉(zhuǎn)賬成功嗎?
I:小明正在轉(zhuǎn)賬時(shí),小李用小明的卡查詢小明的余額,小明的錢少?zèng)]少?
D:如果數(shù)據(jù)庫突然崩潰,保證交易數(shù)據(jù)會(huì)不會(huì)成功保存在數(shù)據(jù)庫中?
ACID
原子性
一個(gè)事務(wù)中的所有操作,要么全部完成,要么全部不完成,不會(huì)結(jié)束在中間某個(gè)環(huán)節(jié)。
事務(wù)在執(zhí)行過程中發(fā)生錯(cuò)誤,會(huì)被回滾(Rollback)到事務(wù)開始前的狀態(tài),就像這個(gè)事務(wù)從來沒有執(zhí)行過一樣。
一致性
事務(wù)的一致性指的是在一個(gè)事務(wù)執(zhí)行之前和執(zhí)行之后數(shù)據(jù)庫都必須處于一致性狀態(tài)。
如果事務(wù)成功地完成,那么系統(tǒng)中所有變化將正確地應(yīng)用,系統(tǒng)處于有效狀態(tài)。
如果在事務(wù)中出現(xiàn)錯(cuò)誤,那么系統(tǒng)中的所有變化將自動(dòng)地回滾,系統(tǒng)返回到原始狀態(tài)。
一致性依賴于原子性和隔離性。
隔離性
指的是在并發(fā)環(huán)境中,當(dāng)不同的事務(wù)同時(shí)操縱相同的數(shù)據(jù)時(shí),每個(gè)事務(wù)都有各自的完整數(shù)據(jù)空間。
由并發(fā)事務(wù)所做的修改必須與任何其他并發(fā)事務(wù)所做的修改隔離。
事務(wù)查看數(shù)據(jù)更新時(shí),數(shù)據(jù)所處的狀態(tài)要么是另一事務(wù)修改它之前的狀態(tài),要么是另一事務(wù)修改它之后的狀態(tài),事務(wù)不會(huì)查看到中間狀態(tài)的數(shù)據(jù)。
持久性
指的是只要事務(wù)成功結(jié)束,它對數(shù)據(jù)庫所做的更新就必須永久保存下來。
即使發(fā)生系統(tǒng)崩潰,重新啟動(dòng)數(shù)據(jù)庫系統(tǒng)后,數(shù)據(jù)庫還能恢復(fù)到事務(wù)成功結(jié)束時(shí)的狀態(tài)。
回到案例
原子性確保了不管交易過程中發(fā)生了什么意外狀況,小明和小紅的金額變動(dòng)要么同時(shí)成功,要么同時(shí)失敗
一致性確保錢不會(huì)在系統(tǒng)內(nèi)憑空產(chǎn)生或消失, 所以小明的轉(zhuǎn)賬是會(huì)被退回的
隔離性保證了在事務(wù)提交之前,其他事務(wù)是無法得知其內(nèi)部變化的,所以小李檢查時(shí)錢不會(huì)少
持久性確保如果事務(wù)剛剛提交,數(shù)據(jù)庫就發(fā)生崩潰,執(zhí)行的結(jié)果依然會(huì)保存在數(shù)據(jù)庫中
ACID根本問題,是針對不同的事務(wù)同時(shí)對同一份數(shù)據(jù)進(jìn)行寫操作的。
實(shí)現(xiàn)原理
InnoDB是MySql中唯一支持事務(wù)的存儲(chǔ)引擎,那么它是如何實(shí)現(xiàn)ACID的呢?
主要通過兩門技術(shù):并發(fā)控制技術(shù)和日志恢復(fù)技術(shù)
并發(fā)控制技術(shù)保證了事務(wù)的隔離性,使數(shù)據(jù)庫的一致性不會(huì)因?yàn)?strong>并發(fā)執(zhí)行的操作被破壞。
日志恢復(fù)技術(shù)保證了事務(wù)的原子性,使一致性、持久性不會(huì)因事務(wù)或系統(tǒng)故障被破壞。
并發(fā)控制
主要就是上鎖,流程如下:
先獲得了鎖,然后才能修改對應(yīng)的數(shù)據(jù)A
事務(wù)完成后釋放鎖,給下一個(gè)要修改數(shù)據(jù)A的事務(wù)
同一時(shí)間,只能有一個(gè)事務(wù)持有數(shù)據(jù)A的互斥鎖
沒有獲取到鎖的事務(wù),需要等待鎖釋放
日志恢復(fù)
Redo Log:
Redo Log記錄的是新數(shù)據(jù)的備份。在事務(wù)提交前,只要將Redo Log持久化即可,不需要將數(shù)據(jù)持久化。當(dāng)系統(tǒng)崩潰時(shí),雖然數(shù)據(jù)沒有持久化,但是Redo Log已經(jīng)持久化。系統(tǒng)可以根據(jù)Redo Log的內(nèi)容,將所有數(shù)據(jù)恢復(fù)到最新的狀態(tài)。
Undo Log:
Undo Log是舊數(shù)據(jù)的備份,在操作任何數(shù)據(jù)之前,首先將數(shù)據(jù)備份到Undo Log,然后進(jìn)行數(shù)據(jù)的修改。如果出現(xiàn)了錯(cuò)誤或者用戶執(zhí)行了回滾語句,系統(tǒng)可以利用Undo Log中的備份將數(shù)據(jù)恢復(fù)到事務(wù)開始之前的狀態(tài)。
事務(wù)的隔離級別
前面提到了,數(shù)據(jù)庫的隔離性是依靠并發(fā)控制來實(shí)現(xiàn)的,也就是通過加鎖來實(shí)現(xiàn)的。
數(shù)據(jù)庫是個(gè)高并發(fā)的應(yīng)用,同一時(shí)間會(huì)有大量的并發(fā)訪問,如果加鎖過度,會(huì)極大的降低并發(fā)處理能力。
所以對于加鎖的處理,就成了數(shù)據(jù)庫的重中之重。
一次封鎖鎖/兩段鎖
一次封鎖法,就是在方法的開始階段,已經(jīng)預(yù)先知道會(huì)用到哪些數(shù)據(jù),然后全部鎖住,在方法運(yùn)行之后,再全部解鎖。
這種方式是最為熟知和常用的方法,可以有效的避免循環(huán)死鎖。
一次封鎖法在數(shù)據(jù)庫中并不好用,因?yàn)樵谑聞?wù)開始階段,數(shù)據(jù)庫并不知道會(huì)用到哪些數(shù)據(jù)。
數(shù)據(jù)庫采用的是兩段鎖,將事務(wù)分成兩個(gè)階段:
加鎖階段:
在對任何數(shù)據(jù)進(jìn)行讀操作之前要申請并獲得S鎖,即共享鎖,其它事務(wù)可以繼續(xù)加共享鎖,但不能加排它鎖。
在進(jìn)行寫操作之前要申請并獲得X鎖,即排它鎖,其它事務(wù)不能再獲得任何鎖。
加鎖不成功,則事務(wù)進(jìn)入等待狀態(tài),直到加鎖成功才繼續(xù)執(zhí)行。
解鎖階段:當(dāng)事務(wù)釋放了一個(gè)封鎖以后,事務(wù)進(jìn)入解鎖階段,在該階段只能進(jìn)行解鎖操作不能再進(jìn)行加鎖操作。
| 事務(wù) | 加鎖/解鎖處理 |
|---|---|
| begin; | |
| insert into test ….. | 加insert對應(yīng)的鎖 |
| update test set… | 加update對應(yīng)的鎖 |
| delete from test …. | 加delete對應(yīng)的鎖 |
| commit; | 事務(wù)提交時(shí),同時(shí)釋放insert、update、delete對應(yīng)的鎖 |
兩段鎖無法避免死鎖,但是兩段鎖協(xié)議可以保證事務(wù)的并發(fā)調(diào)度是串行化,關(guān)于穿行化后面會(huì)進(jìn)行解釋。
四種隔離級別
隱式事務(wù),即單條語句。
前置概念
了解隔離級別之前,我們需要先了解三個(gè)概念,臟讀、幻讀、不可重復(fù)讀。
臟讀
所謂臟讀是指一個(gè)事務(wù)中訪問到了另外一個(gè)事務(wù)未提交的數(shù)據(jù),如圖:
不可重復(fù)讀
一個(gè)事務(wù)讀取同一條記錄2次,得到的結(jié)果不一致,如圖:
幻讀
一個(gè)事務(wù)讀取2次,得到的記錄條數(shù)不一致,如圖:
隔離級別
在數(shù)據(jù)庫操作中,為了有效保證并發(fā)讀取數(shù)據(jù)的正確性,提出的事務(wù)隔離級別。
我們的數(shù)據(jù)庫鎖,也是為了構(gòu)建這些隔離級別存在的。
| 隔離級別 | 臟讀(Dirty Read) | 不可重復(fù)讀(NonRepeatable Read) | 幻讀(Phantom Read) |
|---|---|---|---|
| 未提交讀(Read uncommitted) | ✅ | ✅ | ✅ |
| 已提交讀(Read committed) | ❌ | ✅ | ✅ |
| 可重復(fù)讀(Repeatable read) | ❌ | ❌ | ✅ |
| 可串行化(Serializable ) | ❌ | ❌ | ❌ |
可重復(fù)讀是InnoDB默認(rèn)級別
總結(jié)
事務(wù)的 ACID 四大基本特性在很大程度上保證了數(shù)據(jù)庫的安全運(yùn)行。
雖然ACID有很多好處,但是也有一些缺點(diǎn),尤其是隔離性會(huì)對性能有比較大影響,所以在實(shí)際的使用中我們也會(huì)根據(jù)業(yè)務(wù)的需求對隔離性進(jìn)行調(diào)整。
總結(jié)
以上是生活随笔為你收集整理的搞懂什么是数据库事务的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python量化常用_Python量化常
- 下一篇: 用视频替换直播影像用视频替换直播影像怎么