?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-476679.html
?
目錄
?
?前言:
?介紹事務(wù):
?控制事務(wù):
?事務(wù)四大特性:
?并發(fā)事務(wù)問(wèn)題:
?事務(wù)隔離級(jí)別:
總結(jié):
?
?前言:
這章我們將進(jìn)入到MySQL基礎(chǔ)篇的最后一章:事務(wù),希望大家可以堅(jiān)持下去,跟著我一起走完MySQL的學(xué)習(xí)之旅。
?介紹事務(wù):
MySQL是一種關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng),支持事務(wù)管理。事務(wù)是指一組數(shù)據(jù)庫(kù)操作,它們按照特定的順序執(zhí)行,并且要么全部成功提交,要么全部失敗回滾。在MySQL中,事務(wù)可以用來(lái)保證數(shù)據(jù)的完整性和一致性。
在MySQL中,通過(guò)使用事務(wù),可以保證對(duì)數(shù)據(jù)的操作是可靠和安全的。當(dāng)對(duì)數(shù)據(jù)進(jìn)行復(fù)雜的操作時(shí),使用事務(wù)可以確保一組操作都成功或者都失敗,防止出現(xiàn)數(shù)據(jù)不一致的問(wèn)題。
舉例:
銀行轉(zhuǎn)賬就是一個(gè)典型的事務(wù),如果張三要給李四匯款,那么我們不能分開(kāi)執(zhí)行 給張三扣一千塊,給李四轉(zhuǎn)一千塊,因?yàn)檫@樣如果即使張三沒(méi)有1000元,我們也會(huì)給李四轉(zhuǎn)賬。因此我們應(yīng)該把這兩個(gè)整理成為一個(gè)操作:先給張三扣錢(qián),如果扣錢(qián)成功,再給李四匯款,這樣如果張三的錢(qián)不夠,我們就可以及時(shí)中斷操作,而我們這樣集成多個(gè)操作一起執(zhí)行就叫做定義一個(gè)事務(wù)。
MySQL的事務(wù)時(shí)默認(rèn)自動(dòng)提交的,也就是說(shuō):當(dāng)執(zhí)行一條DML語(yǔ)句的時(shí)候,MySQL會(huì)立即隱式的提交事務(wù)。
控制事務(wù):
- 開(kāi)始事務(wù)(BEGIN):用于明確一個(gè)事務(wù)的開(kāi)始,之后的所有操作都屬于同一個(gè)事務(wù)范圍內(nèi)。
- 提交事務(wù)(COMMIT):用于將一個(gè)事務(wù)提交到數(shù)據(jù)庫(kù)中,表示該事務(wù)所有的修改操作已經(jīng)完成,數(shù)據(jù)已被持久化,該事務(wù)執(zhí)行完成。
- 回滾事務(wù)(ROLLBACK):用于撤銷一個(gè)事務(wù)中發(fā)生的所有修改操作,使得數(shù)據(jù)回到事務(wù)開(kāi)始前的狀態(tài)。當(dāng)一個(gè)事務(wù)無(wú)法完成時(shí),需要撤銷該事務(wù)的所有變更。
1.查看/設(shè)置事務(wù)提交方式
SELECT @@ autocommit;//查詢當(dāng)前事務(wù)提交狀態(tài)
SET @@ cutocommit =0;//1 自動(dòng)提交 0 手動(dòng)提交
2.提交事務(wù)
COMMIT;
3.回滾事務(wù)
ROLLBACK;
控制事務(wù)案例:
1.通過(guò)修改事務(wù)提交方式的方法來(lái)控制事務(wù)
我們可以通過(guò)代碼來(lái)演示剛才所說(shuō)的銀行例子:
二人初始狀態(tài):
我們把事務(wù)提交方式修改為手動(dòng)提交后進(jìn)行轉(zhuǎn)賬操作:
select @@autocommit;
set @@autocommit =0;
-- 1. 查詢張三余額
select * from account where name = '張三';
-- 2. 張三的余額減少1000
update account set money = money - 1000 where name = '張三';
-- 3. 李四的余額增加1000
update account set money = money + 1000 where name = '李四';
?我們此時(shí)如果執(zhí)行這些語(yǔ)句:
結(jié)果:
這是因?yàn)槲覀儼咽聞?wù)提交方式設(shè)置為了手動(dòng)提交,這樣系統(tǒng)執(zhí)行語(yǔ)句并不會(huì)向數(shù)據(jù)庫(kù)提交事務(wù)。
提交事務(wù)(commit):
select @@autocommit;
set @@autocommit =0;
-- 1. 查詢張三余額
select * from account where name = '張三';
-- 2. 張三的余額減少1000
update account set money = money - 1000 where name = '張三';
-- 3. 李四的余額增加1000
update account set money = money + 1000 where name = '李四';
commit;
結(jié)果:
需要注意的是如果我們不提交事務(wù)而不斷執(zhí)行操作,我們并不能夠認(rèn)為這些操作并沒(méi)有執(zhí)行,而是他被存儲(chǔ)在了待執(zhí)行操作里,只要我們提交了事務(wù),這些操作就會(huì)一一執(zhí)行:
?
證明:我們嘗試第一次只進(jìn)行語(yǔ)句執(zhí)行操作不提交,第二次進(jìn)行語(yǔ)句執(zhí)行操作和提交
操作結(jié)果:
2.不通過(guò)修改事務(wù)提交方式來(lái)對(duì)事務(wù)進(jìn)行操作:
1.開(kāi)啟事務(wù)
START TRANSACTION 或 BEGIN;
2.提交事務(wù)
COMMIT;
3.回滾事務(wù)
ROLLBACK;
代碼:?
START TRANSACTION ;
select * from account where name = '張三';
update account set money = money - 1000 where name = '張三';
update account set money = money + 1000 where name = '李四';
COMMIT ;
結(jié)果:
?事務(wù)四大特性:
-
原子性(Atomicity):在一個(gè)事務(wù)中,要么所有的操作都成功提交,要么全部回滾到事務(wù)開(kāi)始前的狀態(tài),保證操作的原子性。
-
一致性(Consistency):事務(wù)執(zhí)行結(jié)束后,數(shù)據(jù)應(yīng)該保持一致性狀態(tài),不管事務(wù)執(zhí)行成功或失敗,數(shù)據(jù)庫(kù)都應(yīng)該滿足預(yù)定義的完整性約束條件。
-
隔離性(Isolation):在一個(gè)事務(wù)執(zhí)行的過(guò)程中,不會(huì)被其他并發(fā)的事務(wù)所干擾,保證了事務(wù)的隔離性。
-
持久性(Durability):事務(wù)提交后,其所做的修改將永久保存到數(shù)據(jù)庫(kù)中。
并發(fā)事務(wù)問(wèn)題:
1. 臟讀(Dirty Read):一個(gè)事務(wù)讀取到了另一個(gè)事務(wù)尚未提交的數(shù)據(jù),如果那個(gè)事務(wù)回滾或者修改了該數(shù)據(jù),可能會(huì)造成數(shù)據(jù)不一致性。
2. 不可重復(fù)讀(Non-repeatable Read):一個(gè)事務(wù)在多次讀取一個(gè)數(shù)據(jù)時(shí),由于這個(gè)數(shù)據(jù)被其他事務(wù)修改導(dǎo)致其多次讀取到不同的結(jié)果,這種情況下,第一個(gè)事務(wù)可能會(huì)認(rèn)為數(shù)據(jù)被修改了多次,但實(shí)際上只是一個(gè)事務(wù)修改了。
3. 幻讀(Phantom Read):一個(gè)事務(wù)在多次讀取一組數(shù)據(jù)時(shí),由于其他事務(wù)插入了新的數(shù)據(jù)導(dǎo)致其讀取到了不同的數(shù)據(jù)行,這種情況下,第一個(gè)事務(wù)可能會(huì)認(rèn)為數(shù)據(jù)被修改或刪除了,但實(shí)際上只是有新的行插入了。
解決這些問(wèn)題的方法通常是加鎖或者使用更高級(jí)的事務(wù)隔離級(jí)別。例如:
1. 通過(guò)在讀取數(shù)據(jù)時(shí)加鎖來(lái)避免臟讀和不可重復(fù)讀,例如使用行鎖或表鎖。
2. 提高事務(wù)隔離級(jí)別,例如升級(jí)到可重復(fù)讀級(jí)別,這樣防止了不可重復(fù)讀,但不能完全避免幻讀。
3. 使用更高級(jí)的隔離級(jí)別,例如串行化,這樣可以同時(shí)避免臟讀、不可重復(fù)讀和幻讀,但也會(huì)對(duì)性能造成一定的影響。
需要根據(jù)具體的業(yè)務(wù)場(chǎng)景、數(shù)據(jù)類型和訪問(wèn)模式選擇合適的解決方案來(lái)保證數(shù)據(jù)的一致性和可靠性。
事務(wù)隔離級(jí)別:
-
讀未提交(Read Uncommitted):一個(gè)事務(wù)可以讀取另一個(gè)未提交的事務(wù)中的數(shù)據(jù)。本級(jí)別隔離最低,會(huì)存在臟讀、不可重復(fù)度和幻讀的問(wèn)題,并發(fā)量最大,性能最優(yōu)。
-
讀已提交(Read Committed):讀取另一并發(fā)事務(wù)提交的變化數(shù)據(jù),讀取操作時(shí)加鎖,所以一定程度上可以避免臟讀。但因?yàn)橐宰x未提交為基礎(chǔ),因此仍然可能出現(xiàn)不可重復(fù)讀和幻讀的問(wèn)題。
-
可重復(fù)讀(Repeatable Read):在一個(gè)事務(wù)中多次讀取同一記錄時(shí),它能夠保證所讀取的數(shù)據(jù)是一樣的,該級(jí)別通過(guò)行級(jí)鎖定已讀取數(shù)據(jù),避免了不可重復(fù)讀,但仍可能出現(xiàn)幻讀。
-
序列化(Serializable):所有事務(wù)順序執(zhí)行,即依次執(zhí)行,不能并發(fā)執(zhí)行,以此保證最高級(jí)別的隔離程度,也保證了隔離級(jí)別下的數(shù)據(jù)一致性。是最保險(xiǎn)的事務(wù)隔離級(jí)別,但并發(fā)性最差,性能最低。
? ? ? ?Repeatable Read是MySQL的默認(rèn)事務(wù)隔離級(jí)別
?語(yǔ)法:
1.查看當(dāng)前事務(wù)隔離級(jí)別
SELECT @@TRANSACTION_ISOLATION;
2.設(shè)置事務(wù)隔離級(jí)別
SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {隔離級(jí)別};
SESSION與GLOBAL區(qū)別:
- SESSION是指在當(dāng)前客戶端設(shè)置隔離級(jí)別
- GLOBAL是指在所有客戶端設(shè)置隔離級(jí)別。
?
總結(jié):
? ? ? ? 本片我們介紹了事務(wù)以及事務(wù)提交問(wèn)題,MySQL數(shù)據(jù)庫(kù)的基礎(chǔ)篇就到此完結(jié)了,下一篇我會(huì)詳細(xì)講解什么是臟讀,幻讀,不可重復(fù)讀。然后會(huì)持續(xù)更新進(jìn)階篇,也就是對(duì)各種語(yǔ)句的優(yōu)化,歡迎大家持續(xù)閱讀。
?
今天的內(nèi)容到這里就結(jié)束了,感謝大家的閱讀。
如果我的內(nèi)容對(duì)你有幫助,請(qǐng)點(diǎn)贊,評(píng)論,收藏。創(chuàng)作不易,大家的支持就是我堅(jiān)持下去的動(dòng)力!
??文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-476679.html
?
到了這里,關(guān)于【MySQL數(shù)據(jù)庫(kù) | 第十五篇】事務(wù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!