當(dāng)多個(gè)用戶訪問(wèn)同一數(shù)據(jù)時(shí)殷费,一個(gè)用戶在更改數(shù)據(jù)的過(guò)程中可能有其它用戶同時(shí)發(fā)起更改請(qǐng)求届惋,為保證數(shù)據(jù)的一致性狀態(tài)鳍悠,MySQL引入了事務(wù)杖们。
本章僅介紹事務(wù)控制語(yǔ)句和隔離級(jí)別恐疲。
本篇文章轉(zhuǎn)載自c語(yǔ)言中文網(wǎng)袭祟,僅僅學(xué)習(xí)淮椰,如有侵權(quán)横缔,請(qǐng)告知?jiǎng)h除镜遣。
數(shù)據(jù)庫(kù)事務(wù)及其特性介紹
數(shù)據(jù)庫(kù)的事務(wù)(Transaction)是一種機(jī)制己肮、一個(gè)操作序列,包含了一組數(shù)據(jù)庫(kù)操作命令。事務(wù)把所有的命令作為一個(gè)整體一起向系統(tǒng)提交或撤銷操作請(qǐng)求谎僻,即這一組數(shù)據(jù)庫(kù)命令要么都執(zhí)行娄柳,要么都不執(zhí)行,因此事務(wù)是一個(gè)不可分割的工作邏輯單元艘绍。
在數(shù)據(jù)庫(kù)系統(tǒng)上執(zhí)行并發(fā)操作時(shí)赤拒,事務(wù)是作為最小的控制單元來(lái)使用的,特別適用于多用戶同時(shí)操作的數(shù)據(jù)庫(kù)系統(tǒng)鞍盗。例如需了,航空公司的訂票系統(tǒng)、銀行般甲、保險(xiǎn)公司以及證券交易系統(tǒng)等肋乍。
事務(wù)具有 4 個(gè)特性,即原子性(Atomicity)敷存、一致性(Consistency)墓造、隔離性(Isolation)和持久性(Durability),這 4 個(gè)特性通常簡(jiǎn)稱為 ACID锚烦。
1. 原子性
事務(wù)是一個(gè)完整的操作觅闽。事務(wù)的各元素是不可分的(原子的)。事務(wù)中的所有元素必須作為一個(gè)整體提交或回滾涮俄。如果事務(wù)中的任何元素失敗蛉拙,則整個(gè)事務(wù)將失敗。
以銀行轉(zhuǎn)賬事務(wù)為例彻亲,如果該事務(wù)提交了孕锄,則這兩個(gè)賬戶的數(shù)據(jù)將會(huì)更新。如果由于某種原因苞尝,事務(wù)在成功更新這兩個(gè)賬戶之前終止了畸肆,則不會(huì)更新這兩個(gè)賬戶的余額,并且會(huì)撤銷對(duì)任何賬戶余額的修改宙址,事務(wù)不能部分提交轴脐。
2. 一致性
當(dāng)事務(wù)完成時(shí),數(shù)據(jù)必須處于一致?tīng)顟B(tài)抡砂。也就是說(shuō)大咱,在事務(wù)開(kāi)始之前,數(shù)據(jù)庫(kù)中存儲(chǔ)的數(shù)據(jù)處于一致?tīng)顟B(tài)注益。在正在進(jìn)行的事務(wù)中徽级,數(shù)據(jù)可能處于不一致的狀態(tài),如數(shù)據(jù)可能有部分被修改聊浅。然而餐抢,當(dāng)事務(wù)成功完成時(shí)现使,數(shù)據(jù)必須再次回到已知的一致?tīng)顟B(tài)。通過(guò)事務(wù)對(duì)數(shù)據(jù)所做的修改不能損壞數(shù)據(jù)旷痕,或者說(shuō)事務(wù)不能使數(shù)據(jù)存儲(chǔ)處于不穩(wěn)定的狀態(tài)碳锈。
以銀行轉(zhuǎn)賬事務(wù)事務(wù)為例。在事務(wù)開(kāi)始之前欺抗,所有賬戶余額的總額處于一致?tīng)顟B(tài)售碳。在事務(wù)進(jìn)行的過(guò)程中,一個(gè)賬戶余額減少了绞呈,而另一個(gè)賬戶余額尚未修改贸人。因此,所有賬戶余額的總額處于不一致?tīng)顟B(tài)佃声。事務(wù)完成以后艺智,賬戶余額的總額再次恢復(fù)到一致?tīng)顟B(tài)。
3. 隔離性
對(duì)數(shù)據(jù)進(jìn)行修改的所有并發(fā)事務(wù)是彼此隔離的圾亏,這表明事務(wù)必須是獨(dú)立的十拣,它不應(yīng)以任何方式依賴于或影響其他事務(wù)。修改數(shù)據(jù)的事務(wù)可以在另一個(gè)使用相同數(shù)據(jù)的事務(wù)開(kāi)始之前訪問(wèn)這些數(shù)據(jù)志鹃,或者在另一個(gè)使用相同數(shù)據(jù)的事務(wù)結(jié)束之后訪問(wèn)這些數(shù)據(jù)夭问。
另外,當(dāng)事務(wù)修改數(shù)據(jù)時(shí)曹铃,如果任何其他進(jìn)程正在同時(shí)使用相同的數(shù)據(jù)缰趋,則直到該事務(wù)成功提交之后,對(duì)數(shù)據(jù)的修改才能生效陕见。張三和李四之間的轉(zhuǎn)賬與王五和趙二之間的轉(zhuǎn)賬秘血,永遠(yuǎn)是相互獨(dú)立的。
4. 持久性
事務(wù)的持久性指不管系統(tǒng)是否發(fā)生了故障淳玩,事務(wù)處理的結(jié)果都是永久的直撤。
一個(gè)事務(wù)成功完成之后非竿,它對(duì)數(shù)據(jù)庫(kù)所作的改變是永久性的蜕着,即使系統(tǒng)出現(xiàn)故障也是如此。也就是說(shuō)红柱,一旦事務(wù)被提交承匣,事務(wù)對(duì)數(shù)據(jù)所做的任何變動(dòng)都會(huì)被永久地保留在數(shù)據(jù)庫(kù)中。
事務(wù)的 ACID 原則保證了一個(gè)事務(wù)或者成功提交锤悄,或者失敗回滾韧骗,二者必居其一。因此零聚,它對(duì)事務(wù)的修改具有可恢復(fù)性袍暴。即當(dāng)事務(wù)失敗時(shí)些侍,它對(duì)數(shù)據(jù)的修改都會(huì)恢復(fù)到該事務(wù)執(zhí)行前的狀態(tài)。
MySQL執(zhí)行事務(wù)的語(yǔ)法和流程
MySQL 提供了多種存儲(chǔ)引擎來(lái)政模。支持事務(wù)的存儲(chǔ)引擎有 InnoDB 和 BDB岗宣,其中,InnoDB 存儲(chǔ)引擎事務(wù)主要通過(guò) UNDO 日志和 REDO 日志實(shí)現(xiàn)淋样,MyISAM 存儲(chǔ)引擎不支持事務(wù)耗式。
拓展:任何一種數(shù)據(jù)庫(kù),都會(huì)擁有各種各樣的日志趁猴,用來(lái)記錄數(shù)據(jù)庫(kù)的運(yùn)行情況刊咳、日常操作、錯(cuò)誤信息等儡司,MySQL 也不例外娱挨。例如,當(dāng)用戶 root 登錄到 MySQL 服務(wù)器枫慷,就會(huì)在日志文件里記錄該用戶的登錄時(shí)間让蕾、執(zhí)行操作等。
為了維護(hù) MySQL 服務(wù)器或听,經(jīng)常需要在 MySQL 數(shù)據(jù)庫(kù)中進(jìn)行日志操作:
? ? ? ? UNDO 日志:復(fù)制事務(wù)執(zhí)行前的數(shù)據(jù)探孝,用于在事務(wù)發(fā)生異常時(shí)回滾數(shù)據(jù)。
? ? ? ? REDO 日志:記錄在事務(wù)執(zhí)行中誉裆,每條對(duì)數(shù)據(jù)進(jìn)行更新的操作顿颅,當(dāng)事務(wù)提交時(shí),該內(nèi)容將被刷新到磁盤(pán)足丢。
默認(rèn)設(shè)置下粱腻,每條 SQL 語(yǔ)句就是一個(gè)事務(wù),即執(zhí)行 SQL 語(yǔ)句后自動(dòng)提交斩跌。
為了達(dá)到將幾個(gè)操作做為一個(gè)整體的目的绍些,需要使用 BEGIN 或 START TRANSACTION 開(kāi)啟一個(gè)事務(wù),或者禁止當(dāng)前會(huì)話的自動(dòng)提交耀鸦。
1. 執(zhí)行事務(wù)的語(yǔ)法和流程
SQL 使用下列語(yǔ)句來(lái)管理事務(wù)柬批。
1) 開(kāi)始事務(wù)
BEGIN;? 或? START TRANSACTION;
2) 提交事務(wù)
COMMIT;
COMMIT 表示提交事務(wù),即提交事務(wù)的所有操作袖订,具體地說(shuō)氮帐,就是將事務(wù)中所有對(duì)數(shù)據(jù)庫(kù)的更新都寫(xiě)到磁盤(pán)上的物理數(shù)據(jù)庫(kù)中,事務(wù)正常結(jié)束洛姑。
提交事務(wù)上沐,意味著將事務(wù)開(kāi)始以來(lái)所執(zhí)行的所有數(shù)據(jù)都修改成為數(shù)據(jù)庫(kù)的永久部分,因此也標(biāo)志著一個(gè)事務(wù)的結(jié)束楞艾。一旦執(zhí)行了該命令参咙,將不能回滾事務(wù)龄广。只有在所有修改都準(zhǔn)備好提交給數(shù)據(jù)庫(kù)時(shí),才執(zhí)行這一操作蕴侧。
3) 回滾(撤銷)事務(wù)
ROLLBACK;
ROLLBACK 表示撤銷事務(wù)蜀细,即在事務(wù)運(yùn)行的過(guò)程中發(fā)生了某種故障,事務(wù)不能繼續(xù)執(zhí)行戈盈,系統(tǒng)將事務(wù)中對(duì)數(shù)據(jù)庫(kù)的所有已完成的操作全部撤銷奠衔,回滾到事務(wù)開(kāi)始時(shí)的狀態(tài)。這里的操作指對(duì)數(shù)據(jù)庫(kù)的更新操作塘娶。
當(dāng)事務(wù)執(zhí)行過(guò)程中遇到錯(cuò)誤時(shí)归斤,使用 ROLLBACK 語(yǔ)句使事務(wù)回滾到起點(diǎn)或指定的保持點(diǎn)處。同時(shí)刁岸,系統(tǒng)將清除自事務(wù)起點(diǎn)或到某個(gè)保存點(diǎn)所做的所有的數(shù)據(jù)修改脏里,并且釋放由事務(wù)控制的資源。因此虹曙,這條語(yǔ)句也標(biāo)志著事務(wù)的結(jié)束迫横。
在 MySQL 中,事務(wù)的默認(rèn)隔離級(jí)別是 REPEATABLE-READ (可重讀)隔離級(jí)別酝碳,即事務(wù)未結(jié)束時(shí)(未執(zhí)行COMMIT或 ROLLBACK)矾踱,其它會(huì)話只能讀取到未提交數(shù)據(jù)。
2. 注意事項(xiàng)
MySQL 事務(wù)是一項(xiàng)非常消耗資源的功能疏哗,大家在使用過(guò)程中要注意以下幾點(diǎn)呛讲。
1) 事務(wù)盡可能簡(jiǎn)短
事務(wù)的開(kāi)啟到結(jié)束會(huì)在數(shù)據(jù)庫(kù)管理系統(tǒng)中保留大量資源,以保證事務(wù)的原子性返奉、一致性贝搁、隔離性和持久性。如果在多用戶系統(tǒng)中芽偏,較大的事務(wù)將會(huì)占用系統(tǒng)的大量資源雷逆,使得系統(tǒng)不堪重負(fù),會(huì)影響軟件的運(yùn)行性能污尉,甚至導(dǎo)致系統(tǒng)崩潰膀哲。
2) 事務(wù)中訪問(wèn)的數(shù)據(jù)量盡量最少
當(dāng)并發(fā)執(zhí)行事務(wù)處理時(shí),事務(wù)操作的數(shù)據(jù)量越少十厢,事務(wù)之間對(duì)相同數(shù)據(jù)的操作就越少等太。
3) 查詢數(shù)據(jù)時(shí)盡量不要使用事務(wù)
對(duì)數(shù)據(jù)進(jìn)行瀏覽查詢操作并不會(huì)更新數(shù)據(jù)庫(kù)的數(shù)據(jù)捂齐,因此應(yīng)盡量不使用事務(wù)查詢數(shù)據(jù)蛮放,避免占用過(guò)量的系統(tǒng)資源。
4) 在事務(wù)處理過(guò)程中盡量不要出現(xiàn)等待用戶輸入的操作
在處理事務(wù)的過(guò)程中奠宜,如果需要等待用戶輸入數(shù)據(jù)包颁,那么事務(wù)會(huì)長(zhǎng)時(shí)間地占用資源瞻想,有可能造成系統(tǒng)阻塞。
總結(jié):
1) 數(shù)據(jù)庫(kù)有增刪改查娩嚼,查的話也是依賴于事務(wù)但不涉及undo數(shù)據(jù)回滾和redo刷新到磁盤(pán)蘑险,這只是個(gè)人理解。事務(wù)的注意事項(xiàng)3可知岳悟,看使用方法得當(dāng)否佃迄,查詢盡量不使用事務(wù)。
2) 數(shù)據(jù)庫(kù)有的需要commit贵少,有的會(huì)自動(dòng)提交呵俏,想必和數(shù)據(jù)庫(kù)設(shè)置了事務(wù)的自動(dòng)提交。MySQL如何設(shè)置事務(wù)自動(dòng)提交呢滔灶?
3)? MySQL中事務(wù)的默認(rèn)隔離級(jí)別是REPEATABLE-READ(可重讀)隔離級(jí)別普碎,這有什么好處?其它的隔離級(jí)別還有哪些呢?
4) MySQL支持事務(wù)數(shù)最大上限是多少?曾經(jīng)遇到一個(gè)問(wèn)題录平,F(xiàn)ireBird事務(wù)超了麻车,數(shù)據(jù)庫(kù)返回904,這也是本篇文章的由來(lái)斗这。