共計(jì) 2336 個(gè)字符,預(yù)計(jì)需要花費(fèi) 6 分鐘才能閱讀完成。
這篇文章主要介紹了 MySQL 事務(wù)的基礎(chǔ)學(xué)習(xí)以及心得分享,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓丸趣 TV 小編帶著大家一起了解一下。
事務(wù)是邏輯上的一組操作,組成這組操作的各個(gè)單元,要不全都成功要不全都失敗,這個(gè)特性就是事務(wù),下面就是關(guān)于 MySQL 事務(wù)學(xué)習(xí)中的心得分享:
事務(wù)的特性
1. 原子性(Atomicity):原子性是指事務(wù)是一個(gè)不可分割的工作單位,事務(wù)中的操作要么都發(fā)生,要么都不發(fā)生。
2. 一致性(Consistency):在一個(gè)事務(wù)中,事務(wù)前后數(shù)據(jù)的完整性必須保持一致,可以想象銀行轉(zhuǎn)賬、火車購(gòu)票。
3. 隔離性(Isolation):多個(gè)事務(wù),事務(wù)的隔離性是指多個(gè)用戶并發(fā)訪問數(shù)據(jù)庫(kù)時(shí),一個(gè)用戶的事務(wù)不能被其它用戶的事務(wù)所干擾,多個(gè)并發(fā)事務(wù)之間數(shù)據(jù)要相互隔離。
4. 持久性(Durability):持久性是指一個(gè)事務(wù)一旦被提交,它對(duì)數(shù)據(jù)庫(kù)中數(shù)據(jù)的改變就是永久性的,接下來(lái)即使數(shù)據(jù)庫(kù)發(fā)生故障也不應(yīng)該對(duì)其有任何影響。
寫這些概念呢,是有點(diǎn)繞!繞就繞吧!反正也不是我規(guī)定的,這是官方的,解釋是我編的!!!
事務(wù)的并發(fā)訪問問題
如果我們?cè)诓豢紤]隔離性問題時(shí),事務(wù)是存在三種并發(fā)訪問問題的。
1. 臟讀:在一個(gè)事務(wù)中,當(dāng)讀取數(shù)據(jù)時(shí),讀到了另一個(gè)事務(wù)未提交的數(shù)據(jù)。
比如 A 賬戶給 B 賬戶轉(zhuǎn)了 1 塊錢,但是 A 沒有提交事務(wù),被 B 賬戶通過臟讀看到了,這時(shí),B 就會(huì)以為 A 已經(jīng)把錢轉(zhuǎn)過來(lái)了,但是這時(shí),A 賬戶回滾事務(wù)。其實(shí)錢就沒給 B 轉(zhuǎn)過去,但是 B 自己本身以為 A 已經(jīng)轉(zhuǎn)過去了,,,有點(diǎn)繞,估計(jì)是我描述到繞!
看代碼:
update account set money=money+1 where name= B -- 此時(shí) A 去通知 B
update account set money=money -1 where name= A
2. 不可重復(fù)讀:在一個(gè)事務(wù)中,兩次讀取的數(shù)據(jù)內(nèi)容不一致,這是因?yàn)樵诓樵儠r(shí),有時(shí)間間隔,數(shù)據(jù)被另一個(gè)事務(wù)已經(jīng)修改提交了,那就會(huì)出現(xiàn)問題。
3. 幻讀 / 虛讀:在一個(gè)事務(wù)中,兩次讀取的數(shù)據(jù)量不一致。
事務(wù)的隔離級(jí)別
上面介紹了 3 種事務(wù)并發(fā)問題!現(xiàn)在介紹一下數(shù)據(jù)庫(kù)提供的解決方案!
1.read uncommitted : 讀取尚未提交的數(shù)據(jù):這個(gè)最低級(jí),但是效率肯定最高,但是哪一個(gè)問題都不能解決。
2.read committed:讀取已經(jīng)提交的數(shù)據(jù):可以解決臟讀 。
3.repeatable read:重讀讀取:可以解決臟讀 和 不可重復(fù)讀。
4.serializable:串行化:可以解決臟讀不可重復(fù)讀和虛讀, 效率最差,相當(dāng)于鎖表,開發(fā)中一般不用。
上面的“2”是 oracle 數(shù)據(jù)庫(kù)默認(rèn)設(shè)置,“3”是 mysql 數(shù)據(jù)庫(kù)默認(rèn)的設(shè)置。
下面呢我就重點(diǎn)解釋一下 mysql 數(shù)據(jù)庫(kù)在上面各種事務(wù)隔離級(jí)別上的演示:
首先介紹兩個(gè)語(yǔ)法:
1. 查看 mysql 數(shù)據(jù)庫(kù)默認(rèn)的隔離級(jí)別:select @@tx_isolation
如圖:
2. 設(shè)置 mysql 的隔離級(jí)別:set session transaction isolation level 事務(wù)的隔離級(jí)別
如圖:
事務(wù)的隔離級(jí)別演示
注意:如果要自己模擬要開啟兩個(gè) mysql 客戶端,也就是模擬兩個(gè)用戶!
1.read uncommitted
如圖:
我通過語(yǔ)法將數(shù)據(jù)庫(kù)的事務(wù)隔離級(jí)別改為了 read uncommitted。
首先我有一張 account 表。
如圖:窗口一
窗口二
數(shù)據(jù)庫(kù)表原始數(shù)據(jù) money 都是 5000,當(dāng)我啟動(dòng)事務(wù)后,在 zhangsan 賬戶增加了 1000 和在李四賬戶減去了 1000,但是我的事務(wù)還未提交,但是我再次查詢數(shù)據(jù)庫(kù)表時(shí),數(shù)據(jù)已經(jīng)發(fā)生變化,這就是臟讀和不可重復(fù)讀!
幻讀 / 虛讀我就不掩飾了,同樣存在!
2.read committed
如圖:
我將數(shù)據(jù)庫(kù)事務(wù)隔離性改為了 read committted。
還是上面那張表:
如圖:窗口一
窗口二
數(shù)據(jù)庫(kù)表 zhangsan 賬戶的 money 和 lisi 賬戶的 money 都發(fā)生了變化,我未提交事務(wù),在另一個(gè)窗口事務(wù)開啟下查詢時(shí),沒有出現(xiàn)臟讀,但是當(dāng)我提交事務(wù)時(shí),在另一個(gè)窗口的事務(wù)下再次查詢,出現(xiàn)了不可重復(fù)讀的情況,這樣可以避免臟讀,但是查詢時(shí)已經(jīng)出現(xiàn)不可重復(fù)讀和幻讀 / 虛讀!
3.repeatable read
如圖:
我將數(shù)據(jù)庫(kù)事務(wù)隔離性改為了 read committted。
還是上面那張表:
如圖:窗口一
窗口二
我在兩個(gè)窗口都開啟了事務(wù),當(dāng)窗口一進(jìn)行數(shù)據(jù)操作后,并進(jìn)行事務(wù)提交,在窗口二的事務(wù)開啟情況下,我去查詢,沒有查詢到剛才窗口一的數(shù)據(jù)操作記錄,這樣就避免了臟讀和不可重復(fù)讀。
有人說也避免了虛讀 / 幻讀,其實(shí)沒有。
看圖:
我在操作 lisi 賬戶時(shí),數(shù)據(jù)只是發(fā)生修改的變化,但是當(dāng)我修改 wangwu 這個(gè)賬戶時(shí),再去查詢出現(xiàn)了 wangwu,賬戶的數(shù)據(jù),但是其實(shí)在我未操作前,wangwu 賬戶的數(shù)據(jù)是查詢不出的。這就是幻讀 / 虛讀!
如果不理解幻讀 / 虛讀這塊,可以查一下 InnoDB。
4.serializable
我就不演示了,開發(fā)不建議用,效率又慢,但是所有的問題都能避免!!
總結(jié)一下
事務(wù)隔離級(jí)別的性能:
read uncommitted read committed repeatable read serialazable
事務(wù)隔離級(jí)別的安全性:
read uncommitted read committed repeatable read serialazable
mysql 事務(wù)控制:
開啟事務(wù):start transaction;
提交:commit;
回滾:rollback;
感謝你能夠認(rèn)真閱讀完這篇文章,希望丸趣 TV 小編分享的“MySQL 事務(wù)的基礎(chǔ)學(xué)習(xí)以及心得分享”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持丸趣 TV,關(guān)注丸趣 TV 行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來(lái)學(xué)習(xí)!