MySQL事務(wù)的ACID特性以及并發(fā)問(wèn)題方案
一、事務(wù)的概念
一個(gè)事務(wù)是由一條或多條對(duì)數(shù)據(jù)庫(kù)操作的SQL語(yǔ)句所組成的一個(gè)不可分割的單元,只有當(dāng)事務(wù)中所有操作都正常執(zhí)行完了,整個(gè)事務(wù)才會(huì)被提交給數(shù)據(jù)庫(kù),如果有部分事務(wù)處理失敗,那么事務(wù)就要回滾到最初的狀態(tài),因此,事務(wù)要么全部執(zhí)行成功,要么全部失敗。
所以要記住事務(wù)幾個(gè)基本概念,如下:
事務(wù)是一組SQL語(yǔ)句的執(zhí)行,要么全部成功,要么全部失敗,不能出現(xiàn)部分成功,部分失敗的結(jié)果,保證事務(wù)執(zhí)行的原子操作。事務(wù)的所有SQL語(yǔ)句全部執(zhí)行成功,才能提交(commit)事務(wù),把結(jié)果寫(xiě)會(huì)磁盤(pán)上。事務(wù)執(zhí)行過(guò)程中,有的SQL出現(xiàn)錯(cuò)誤,那么事務(wù)必須要回滾(rollback)到最初的狀態(tài)。
比如轉(zhuǎn)賬業(yè)務(wù)需要多條SQL語(yǔ)句共同完成,只有這些SQL都執(zhí)行成功才算業(yè)務(wù)成功了。
事務(wù)處理有三個(gè)狀態(tài):
begin:開(kāi)啟一個(gè)事務(wù)要執(zhí)行的全部sql語(yǔ)句都成功了,然后commit提交一個(gè)事務(wù)如果其中任何一條SQL語(yǔ)句由于停電、或者服務(wù)器出錯(cuò),導(dǎo)致SQL執(zhí)行異常,那事務(wù)就沒(méi)有提交,事務(wù)會(huì)回滾(rollback),數(shù)據(jù)將恢復(fù)到事務(wù)開(kāi)始前的狀態(tài)
這是存儲(chǔ)引擎來(lái)保證的(redo log和undo log保證的)
MyISAM存儲(chǔ)引擎不支持事務(wù),InnoDB存儲(chǔ)引擎支持事務(wù)、支持行鎖。
用show engines\G
查看當(dāng)前數(shù)據(jù)庫(kù)支持哪些存儲(chǔ)引擎。
select @@autocommit;
查看對(duì)事務(wù)提交狀態(tài)的設(shè)置
數(shù)據(jù)庫(kù)引擎可以通過(guò)命令臨時(shí)修改,或者通過(guò)配置文件永久修改。
如果說(shuō)我們業(yè)務(wù)上涉及了事務(wù),我們一般會(huì)在代碼上控制這個(gè)變量,一般來(lái)說(shuō),我們的事務(wù)由多條SQL組成,要滿足事務(wù)的原子性操作,所以我們?cè)O(shè)置為手動(dòng)提交。業(yè)務(wù)都成功,則提交這個(gè)事務(wù);如果業(yè)務(wù)中間出現(xiàn)失敗,就回滾1個(gè)事務(wù)。
二、ACID特性
每一個(gè)事務(wù)必須滿足下面的4個(gè)特性:
事務(wù)的原子性(Atomic):事務(wù)是一個(gè)不可分割的整體,事務(wù)必須具有原子特性,及當(dāng)事務(wù)修改時(shí),要么全執(zhí)行,要么全不執(zhí)行,即不允許事務(wù)部分的完成。事務(wù)的一致性(Consistency):一個(gè)事務(wù)執(zhí)行之前和執(zhí)行之后,數(shù)據(jù)庫(kù)數(shù)據(jù)必須保持一致性狀態(tài)。數(shù)據(jù)庫(kù)的一致性狀態(tài)必須由用戶來(lái)負(fù)責(zé),由并發(fā)控制機(jī)制實(shí)現(xiàn)。就拿網(wǎng)上購(gòu)物來(lái)說(shuō),你只有讓商品出庫(kù),又讓商品進(jìn)入顧客的購(gòu)物車(chē)才能構(gòu)成一個(gè)完整的事務(wù)。(一致性不僅僅體現(xiàn)在事務(wù)里面,包括存儲(chǔ)層引入MySQL為了提高熱點(diǎn)數(shù)據(jù)的訪問(wèn)效率一般都會(huì)加一個(gè)緩存層Redis或者M(jìn)emery cache對(duì)熱點(diǎn)數(shù)據(jù)做緩存,這就涉及了緩存層和數(shù)據(jù)庫(kù)DB層的數(shù)據(jù)一致性問(wèn)題)事務(wù)的隔離性(Isolution):當(dāng)兩個(gè)或多個(gè)事務(wù)并發(fā)執(zhí)行時(shí),為了保證數(shù)據(jù)的安全性,將一個(gè)事務(wù)內(nèi)部的操作與其他事務(wù)的操作隔離起來(lái),不被其他正在執(zhí)行的事務(wù)所看到,使得并發(fā)執(zhí)行的各個(gè)事務(wù)之間不能互相影響。隔離級(jí)別:數(shù)據(jù)的安全性和事務(wù)的并發(fā)性。隔離越嚴(yán)格,安全性越高,并發(fā)性越低(就是并發(fā)控制,保證數(shù)據(jù)安全)事務(wù)的持久性(Durability):事務(wù)完成以后(事務(wù)commit成功),DBMS保證它對(duì)數(shù)據(jù)庫(kù)中的數(shù)據(jù)的修改時(shí)永久性的,即使數(shù)據(jù)庫(kù)因?yàn)楣收铣鲥e(cuò),也應(yīng)該能夠恢復(fù)數(shù)據(jù)。
MySQL最重要的是日志,不是數(shù)據(jù)!
事務(wù)的ACD特性是由MySQL的redo log和undo log機(jī)制來(lái)保證的;I隔離性是由mysql事務(wù)的鎖機(jī)制來(lái)實(shí)現(xiàn)保證的。
三、事務(wù)并發(fā)存在的問(wèn)題
事務(wù)處理不經(jīng)隔離,并發(fā)執(zhí)行事務(wù)時(shí)通常會(huì)發(fā)生以下問(wèn)題:
臟讀(Dirty Read):一個(gè)事務(wù)讀取了另一個(gè)事務(wù)未提交的數(shù)據(jù)。例如當(dāng)事務(wù)A和事務(wù)B并發(fā)執(zhí)行時(shí),當(dāng)事務(wù)A更新后,事務(wù)B查詢讀取到A尚未提交的數(shù)據(jù),此時(shí)事務(wù)A回滾,則事務(wù)B讀到的數(shù)據(jù)就是無(wú)效的臟數(shù)據(jù)(事務(wù)B讀取了事務(wù)A尚未提交的數(shù)據(jù))不可重復(fù)讀(NonRepeatable Read):一個(gè)事務(wù)的操作導(dǎo)致另一個(gè)事務(wù)前后兩次讀到不同的數(shù)據(jù)。例如當(dāng)事務(wù)A和事務(wù)B并發(fā)執(zhí)行時(shí),當(dāng)事務(wù)B查詢讀取數(shù)據(jù)后,事務(wù)A更新操作更改事務(wù)B查詢到的數(shù)據(jù),此時(shí)事務(wù)B再去讀該數(shù)據(jù),發(fā)現(xiàn)前后兩次讀的數(shù)據(jù)不一樣。(事務(wù)B讀取了事務(wù)A已提交的數(shù)據(jù))虛讀(Phantom Read)幻讀:一個(gè)事務(wù)的操作導(dǎo)致另一個(gè)事務(wù)前后兩次查詢的結(jié)果數(shù)據(jù)量不同。例如當(dāng)事務(wù)A和事務(wù)B并發(fā)執(zhí)行時(shí),當(dāng)事務(wù)B查詢讀取數(shù)據(jù)后,事務(wù)A新增或者刪除了一條滿足事務(wù)B查詢條件的記錄,此時(shí)事務(wù)B再去查詢,發(fā)現(xiàn)查詢到前一次不存在的記錄,或者前一次查詢的一些記錄不見(jiàn)了。(事務(wù)B讀取了事務(wù)A新增加的數(shù)據(jù)或者讀不到事務(wù)A刪除的數(shù)據(jù))
臟讀必須杜絕,因?yàn)槭聞?wù)沒(méi)有commit。在有些場(chǎng)景下,不可重復(fù)讀和幻讀是可以允許的(事務(wù)已經(jīng)commit),不一定非要杜絕(通過(guò)設(shè)置不同的隔離級(jí)別解決),由應(yīng)用場(chǎng)景需求決定。
四、事務(wù)相關(guān)命令
select @@autocommit;
查看MySQL是否自動(dòng)提交事務(wù)
0表示手動(dòng)提交事務(wù),1表示自動(dòng)提交事務(wù),設(shè)置事務(wù)提交方式為手動(dòng)提交(只影響當(dāng)前session):
到此這篇關(guān)于MySQL事務(wù)的ACID特性以及并發(fā)問(wèn)題方案的文章就介紹到這了,更多相關(guān)MySQL事務(wù)ACID特性內(nèi)容請(qǐng)搜索本站以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持本站!
版權(quán)聲明:本站文章來(lái)源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請(qǐng)保持原文完整并注明來(lái)源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來(lái)源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來(lái),僅供學(xué)習(xí)參考,不代表本站立場(chǎng),如有內(nèi)容涉嫌侵權(quán),請(qǐng)聯(lián)系alex-e#qq.com處理。