【MySQL】——事务的基本概念
- 💂 個人主頁:努力學(xué)習(xí)的少年
- 🤟 版權(quán):?本文由【努力學(xué)習(xí)的少年】原創(chuàng)、在CSDN首發(fā)、需要轉(zhuǎn)載請聯(lián)系博主
- 💬 如果文章對你有幫助、歡迎關(guān)注、點贊、收藏(一鍵三連)和訂閱專欄哦
一. 事務(wù)的概念
在MySQL環(huán)境中,事務(wù)是由一個單元的一個或多個SQL語句組成,這個單元的每個SQL語句是相互依賴的,而且單元作為一個整體是不可分割的。如果單元中的一個語句不能完成,整個單元就會回滾(撤銷),所有影響到數(shù)據(jù)將返回到事務(wù)開始以前的狀態(tài),因此,只有事務(wù)中所有SQL語句執(zhí)行成功,則才能說明這個事務(wù)被成功執(zhí)行。使用一個簡單的例子來理解事務(wù):
向公司添加一名新員工,這個過程由3個基本步驟組成(如圖所示):
- 在員工數(shù)據(jù)庫中為員工創(chuàng)建一條新記錄(分配員工ID,分配崗位等)。
- 為新員工分配部門。
- 建立員工的工資和獎金記錄。
??? 如果其中一個步驟失敗,則系統(tǒng)必須撤銷在此之前的所有變化,刪除所有不完整的記錄的痕跡,以避免以后的不一致和計算錯誤。
???在 開始事務(wù) 和 提交事務(wù) 之間所作的所有操作 構(gòu)成一個事務(wù), 其中任何一個步驟失敗都會都會導(dǎo)致整個事務(wù)被撤銷,系統(tǒng)會返回到以前的狀態(tài)。
事務(wù)提交后,對數(shù)據(jù)的修改是永久的,即使系統(tǒng)出現(xiàn)故障也不會丟失數(shù)據(jù)。
二.事務(wù)的操作
1.事務(wù)的提交
事務(wù)的提交方式有 自動提交,手動提交 。
在MySQL命令行的默認(rèn)下,事務(wù)都是自動提交的,即執(zhí)行SQL語句后會馬上執(zhí)行commit操作,我們之前所寫的所有單條的DML SQL語句,在MySQL默認(rèn)是一個事務(wù),默認(rèn)執(zhí)行完,就會被MySQL自動提交。
如果要受到的提交可以使用 begin 或者 start transaction,或者將 AUTOCOMMIT=0,表示禁用自動提交。如下:
show variables like 'autocommit';//查看是否啟動為自動提交。 SET AUTOCOMMIT=0;//禁用自動提交2.開始事務(wù)
手動啟動一個事務(wù)可以采用如下語句:
start transaction; 或者 begin;begin 和? commit 之間的所有操作 統(tǒng)稱為一個事務(wù)。
?3.結(jié)束事務(wù)
commit語句是提交語句,它使得自從事務(wù)開始以來所執(zhí)行的所有數(shù)據(jù)修改成為數(shù)據(jù)庫的永久部分,也標(biāo)記一個事務(wù)的結(jié)束。
4.事務(wù)的回滾
事務(wù)回滾有語句有
- rollback :直接回滾到事務(wù)的最開始,也就是撤銷了該事務(wù)的所有操作。
- rollback to 保存點名稱:回滾到設(shè)置保存點的位置,撤銷了設(shè)置保存點之后的所有操作。
- savepoint 名稱:設(shè)置保存點,并設(shè)置保存點的名稱。
三.事務(wù)的屬性
在MySQL中只有使用了 Innodb存儲引擎 的數(shù)據(jù)表才支持事務(wù),MyISAM不支持。
事務(wù)的屬性包括 原子性,一致性,隔離性,永久性。
原子性
原子性 意味著每個事務(wù)都必須看作一個不可分割的單元,假設(shè)一個事務(wù)由兩個或多個操作組成,其中這些操作必須同時成功,則整個事務(wù)才成功,否則事務(wù)失敗,失敗將會返回該事務(wù)以前的狀態(tài)。
在添加員工這個例子中,原子性指如果沒有創(chuàng)建員工的工資表和部門,就不可能將員工插入到數(shù)據(jù)庫表中??偠灾?#xff0c;原子執(zhí)行是一個或者全部發(fā)送或者什么也沒有發(fā)生的命題。
一致性
事務(wù)
隔離性
數(shù)據(jù)庫允許多個并發(fā)事務(wù)同時對其數(shù)據(jù)進(jìn)行讀寫和修改的能力,隔離性可以 防止多個事務(wù)并發(fā)執(zhí)行時 由于多個事務(wù)的交叉執(zhí)行 導(dǎo)致數(shù)據(jù)庫中的數(shù)據(jù)的不一致。比如:事務(wù)A正在不斷的在修改表中的數(shù)據(jù),那么事務(wù)B需要不斷的查看表的數(shù)據(jù),那么事務(wù)B每次查看的數(shù)據(jù)可能不一樣。
持久性
事務(wù)提交后,對數(shù)據(jù)的修改就是 永久的,即便系統(tǒng)故障也不會丟失。
一致性
為了理解一致性,舉個通俗易懂的例子:假設(shè)我要提現(xiàn)1500塊錢提現(xiàn)到銀行卡中,那么就需要至少需要分兩步操作:
- 當(dāng)?shù)谝徊綀?zhí)行后,服務(wù)器出現(xiàn)問題導(dǎo)致第二步就無法完成,那么我們的微信錢包-1500快錢,銀行卡上的錢沒有增加,導(dǎo)致我白白丟失了1500塊錢,這就導(dǎo)致數(shù)據(jù)“不一致"的問題.
- 事務(wù)的一致性與事務(wù)原子性有關(guān),如果第二步執(zhí)行失敗,則會回滾到事務(wù)的開始,撤銷第一步的操作,所以為了保持事務(wù)的一致性,在業(yè)務(wù)層上設(shè)計上,就要求我們合理的設(shè)計這兩步操作,需要將上面的兩個操作設(shè)計在一個事務(wù)內(nèi)。
四. 隔離級別
1.如何理解隔離級別
- MySQL服務(wù)可能被多個客戶端同時給訪問,訪問的方式是以事務(wù)的形式訪問。
- 一個事務(wù)由多條SQL語句組成,任何一個事務(wù)都有執(zhí)行前(begin之前),執(zhí)行中(begin和commit之間),執(zhí)行后(commit之后),如果所有的事務(wù)各自執(zhí)行中有多條事務(wù)語句,那么可能會相互影響到的情況,例如:多個事務(wù)訪問同一張表,同一行數(shù)據(jù),有些事務(wù)在修改,有些事務(wù)在讀取。
- 數(shù)據(jù)庫中為了保證事務(wù)的過程中盡量不受干擾,就有了一個重要特征:隔離性。
- 數(shù)據(jù)庫中,允許事務(wù)受不同程度的干擾,就有了一種重要的特征:隔離級別。
2. 隔離級別的分類
SQL標(biāo)準(zhǔn)定義了4類隔離級別,包括一些具體規(guī)則,用來 限定事務(wù)內(nèi)外的哪些改變是可見的,哪些是不可見的,低級別的隔離級別一般支持更高的并發(fā)處理,并擁有更低的系統(tǒng)開銷。不同的場景使用的隔離級別可能不同。
讀未提交(READ UNCOMMITTED)
- 所有的事務(wù)可以看到其它事務(wù)未提交的結(jié)果。讀未提交隔離級別很少應(yīng)用于實際應(yīng)用中。
- 一個事務(wù)在執(zhí)行中,讀到另一個事務(wù)正在更新但沒有提交的數(shù)據(jù),這種現(xiàn)象就為臟讀。
查看客戶端的隔離級別:
select @@tx_isolation; //查看隔離級別?將當(dāng)前會話的事務(wù)A的隔離級別設(shè)置為讀未提交READ-UNCOMMITTED;
set session tx_isolation='READ-UNCOMMITTED';?如果要設(shè)置全局的事務(wù)隔離級別(其他會話也會改變),那么需要將session 更改為global,如果隔離級別沒有生效,則需要重新登錄會話才會生效。
set global tx_isolation='READ-UNCOMMITTED';?實驗1:觀察讀未提交的現(xiàn)象
客戶端A開始一個事務(wù),并往person表中插入數(shù)據(jù),客戶端B啟動一個事務(wù)并查看person表。
person表:
客戶端A:
?客戶端B:
- 客戶端A沒有提交事務(wù),但是客戶端B的事務(wù)可以看到客戶端A事務(wù)執(zhí)行過程中插入的數(shù)據(jù),這就是讀未提交的現(xiàn)象。
- 客戶端B的事務(wù) 看到 客戶端A的事務(wù) 對表的操作,這就是臟讀。
讀提交(READ COMMIT)
- 一個事務(wù) 只能看到 已經(jīng)提交事務(wù)的操作,正在執(zhí)行的事務(wù)的操作是看不到的,這種隔離級別也支持所謂的不可重復(fù)讀,因為同一事務(wù)的其他實例在該實例處理期間可能會有新的commit,所以同一事務(wù)進(jìn)行查詢時可能會返回不同的結(jié)果。
- 該隔離級別是大部分?jǐn)?shù)據(jù)庫的隔離級別,但不是MySQL的隔離級別。
實驗2:查看讀提交的現(xiàn)象
將隔離級別設(shè)置為讀提交,客戶端A啟動一個事務(wù)并給person表插入數(shù)據(jù),客戶端B查看person表,接下來客戶端A提交事務(wù),客戶端A再查看person表。
?person表:
客戶端A插入數(shù)據(jù),但沒有提交事務(wù),客戶端B查看不到插入的數(shù)據(jù):
?客戶端A提交事務(wù),客戶端B可以查看到客戶端A插入的數(shù)據(jù):
客戶端B的事務(wù)只能查看到客戶端A事務(wù)提交的數(shù)據(jù),這就是讀提交。
實驗3:查看不可重復(fù)讀的現(xiàn)象
客戶端B開始一個事務(wù)并查看person表,然后客戶端A開始一個事務(wù)并修改person表中的關(guān)羽的qq值,然后提交,最后客戶端B再查看person表中的數(shù)據(jù).
person表:
客戶端A:
?客戶端B:
?????
客戶端A事務(wù)提交事務(wù)前和提交事務(wù)后,客戶端B的事務(wù)查看表的數(shù)據(jù)是不一致的,這就是不可重復(fù)讀的現(xiàn)象。
可重復(fù)讀(REPEATABLE READ)
- 可重復(fù)讀是MySQL的默認(rèn)事務(wù)隔離級別。
- 可重復(fù)讀隔離級別只允許讀取已經(jīng)提交的記錄,而且在 同一個事務(wù)兩次讀取一個記錄期間保持一致,但是該事務(wù)不要求于其他事務(wù)可串行化。
- 一個事務(wù)可以到由一個已經(jīng)提交更新的記錄,但是可能出現(xiàn)幻讀的問題。
- 幻讀指當(dāng)用戶讀數(shù)據(jù)行時,另一個事務(wù)又在該范圍內(nèi)插入了新行,當(dāng)用戶在讀取該范圍的數(shù)據(jù)行,讀取到的記錄是不一樣的。
- 但是MySQL通過多版本并發(fā)控制機(jī)制解決了幻讀的問題。
實驗4:查看可重復(fù)讀的現(xiàn)象
將隔離級別設(shè)置為可重復(fù)讀。
客戶端B開始一個事務(wù)并查看person表,然后客戶端A開始一個事務(wù)并修改person表中的關(guān)羽的qq值,然后提交,最后客戶端B再查看person表中的數(shù)據(jù).
person表:
?客戶端A:
?客戶端B:
??????
?由上面實驗可以看到,客戶端A的事務(wù)修改數(shù)據(jù)后,不管有沒有提交事務(wù),客戶端B每次查看數(shù)據(jù)時只會顯示第一次查看到的數(shù)據(jù),且在一個事務(wù)內(nèi)只能讀取一個記錄,期間保持一致,直到客戶端B將事務(wù)提交,才能讀取別的事務(wù)修改的記錄。
.
串行化(SERIALIZABLE)
- ?串行化是最高的隔離級別,它通過強(qiáng)制事務(wù)排序,可串行化是一個調(diào)度,即多個事務(wù)之間的執(zhí)行方式;而多個事務(wù)之間的執(zhí)行有個先后順序,如果事務(wù)之間沒有共同的操作對象(讀或?qū)懖僮?#xff09;,則事務(wù)之間的執(zhí)行順序前后置換是沒有關(guān)系的;但是如果事物間存在共同的操作對象,則事務(wù)間先后執(zhí)行的順序則需要區(qū)分 。
- 序列化是最高的事務(wù)隔離級別,在該級別下,事務(wù)串行化順序執(zhí)行,可以避免臟讀、不可重復(fù)讀與幻讀。但是這種事務(wù)隔離級別效率低下,比較耗數(shù)據(jù)庫性能,一般不使用 ????
總結(jié)
以上是生活随笔為你收集整理的【MySQL】——事务的基本概念的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HTML5七夕情人节表白网页(抖音-罗盘
- 下一篇: maptalk(2) -marker文字