您好,登錄后才能下訂單哦!
這篇“MySQL事務(wù)的ACID特性及并發(fā)問題怎么解決”文章的知識點大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“MySQL事務(wù)的ACID特性及并發(fā)問題怎么解決”文章吧。
一個事務(wù)是由一條或多條對數(shù)據(jù)庫操作的SQL語句所組成的一個不可分割的單元,只有當(dāng)事務(wù)中所有操作都正常執(zhí)行完了,整個事務(wù)才會被提交給數(shù)據(jù)庫,如果有部分事務(wù)處理失敗,那么事務(wù)就要回滾到最初的狀態(tài),因此,事務(wù)要么全部執(zhí)行成功,要么全部失敗。
所以要記住事務(wù)幾個基本概念,如下:
事務(wù)是一組SQL語句的執(zhí)行,要么全部成功,要么全部失敗,不能出現(xiàn)部分成功,部分失敗的結(jié)果,保證事務(wù)執(zhí)行的原子操作。事務(wù)的所有SQL語句全部執(zhí)行成功,才能提交(commit)事務(wù),把結(jié)果寫會磁盤上。事務(wù)執(zhí)行過程中,有的SQL出現(xiàn)錯誤,那么事務(wù)必須要回滾(rollback)到最初的狀態(tài)。
比如轉(zhuǎn)賬業(yè)務(wù)需要多條SQL語句共同完成,只有這些SQL都執(zhí)行成功才算業(yè)務(wù)成功了。
事務(wù)處理有三個狀態(tài):
begin:開啟一個事務(wù)要執(zhí)行的全部sql語句都成功了,然后commit提交一個事務(wù)如果其中任何一條SQL語句由于停電、或者服務(wù)器出錯,導(dǎo)致SQL執(zhí)行異常,那事務(wù)就沒有提交,事務(wù)會回滾(rollback),數(shù)據(jù)將恢復(fù)到事務(wù)開始前的狀態(tài)
這是存儲引擎來保證的(redo log和undo log保證的)
MyISAM存儲引擎不支持事務(wù),InnoDB存儲引擎支持事務(wù)、支持行鎖。
用show engines\G
查看當(dāng)前數(shù)據(jù)庫支持哪些存儲引擎。
select @@autocommit;
查看對事務(wù)提交狀態(tài)的設(shè)置
數(shù)據(jù)庫引擎可以通過命令臨時修改,或者通過配置文件永久修改。
如果說我們業(yè)務(wù)上涉及了事務(wù),我們一般會在代碼上控制這個變量,一般來說,我們的事務(wù)由多條SQL組成,要滿足事務(wù)的原子性操作,所以我們設(shè)置為手動提交。業(yè)務(wù)都成功,則提交這個事務(wù);如果業(yè)務(wù)中間出現(xiàn)失敗,就回滾1個事務(wù)。
每一個事務(wù)必須滿足下面的4個特性:
事務(wù)的原子性(Atomic):事務(wù)是一個不可分割的整體,事務(wù)必須具有原子特性,及當(dāng)事務(wù)修改時,要么全執(zhí)行,要么全不執(zhí)行,即不允許事務(wù)部分的完成。事務(wù)的一致性(Consistency):一個事務(wù)執(zhí)行之前和執(zhí)行之后,數(shù)據(jù)庫數(shù)據(jù)必須保持一致性狀態(tài)。數(shù)據(jù)庫的一致性狀態(tài)必須由用戶來負責(zé),由并發(fā)控制機制實現(xiàn)。就拿網(wǎng)上購物來說,你只有讓商品出庫,又讓商品進入顧客的購物車才能構(gòu)成一個完整的事務(wù)。(一致性不僅僅體現(xiàn)在事務(wù)里面,包括存儲層引入MySQL為了提高熱點數(shù)據(jù)的訪問效率一般都會加一個緩存層Redis或者Memery cache對熱點數(shù)據(jù)做緩存,這就涉及了緩存層和數(shù)據(jù)庫DB層的數(shù)據(jù)一致性問題)事務(wù)的隔離性(Isolution):當(dāng)兩個或多個事務(wù)并發(fā)執(zhí)行時,為了保證數(shù)據(jù)的安全性,將一個事務(wù)內(nèi)部的操作與其他事務(wù)的操作隔離起來,不被其他正在執(zhí)行的事務(wù)所看到,使得并發(fā)執(zhí)行的各個事務(wù)之間不能互相影響。隔離級別:數(shù)據(jù)的安全性和事務(wù)的并發(fā)性。隔離越嚴格,安全性越高,并發(fā)性越低(就是并發(fā)控制,保證數(shù)據(jù)安全)事務(wù)的持久性(Durability):事務(wù)完成以后(事務(wù)commit成功),DBMS保證它對數(shù)據(jù)庫中的數(shù)據(jù)的修改時永久性的,即使數(shù)據(jù)庫因為故障出錯,也應(yīng)該能夠恢復(fù)數(shù)據(jù)。
MySQL最重要的是日志,不是數(shù)據(jù)!
事務(wù)的ACD特性是由MySQL的redo log和undo log機制來保證的;I隔離性是由mysql事務(wù)的鎖機制來實現(xiàn)保證的。
事務(wù)處理不經(jīng)隔離,并發(fā)執(zhí)行事務(wù)時通常會發(fā)生以下問題:
臟讀(Dirty Read):一個事務(wù)讀取了另一個事務(wù)未提交的數(shù)據(jù)。例如當(dāng)事務(wù)A和事務(wù)B并發(fā)執(zhí)行時,當(dāng)事務(wù)A更新后,事務(wù)B查詢讀取到A尚未提交的數(shù)據(jù),此時事務(wù)A回滾,則事務(wù)B讀到的數(shù)據(jù)就是無效的臟數(shù)據(jù)(事務(wù)B讀取了事務(wù)A尚未提交的數(shù)據(jù))不可重復(fù)讀(NonRepeatable Read):一個事務(wù)的操作導(dǎo)致另一個事務(wù)前后兩次讀到不同的數(shù)據(jù)。例如當(dāng)事務(wù)A和事務(wù)B并發(fā)執(zhí)行時,當(dāng)事務(wù)B查詢讀取數(shù)據(jù)后,事務(wù)A更新操作更改事務(wù)B查詢到的數(shù)據(jù),此時事務(wù)B再去讀該數(shù)據(jù),發(fā)現(xiàn)前后兩次讀的數(shù)據(jù)不一樣。(事務(wù)B讀取了事務(wù)A已提交的數(shù)據(jù))虛讀(Phantom Read)幻讀:一個事務(wù)的操作導(dǎo)致另一個事務(wù)前后兩次查詢的結(jié)果數(shù)據(jù)量不同。例如當(dāng)事務(wù)A和事務(wù)B并發(fā)執(zhí)行時,當(dāng)事務(wù)B查詢讀取數(shù)據(jù)后,事務(wù)A新增或者刪除了一條滿足事務(wù)B查詢條件的記錄,此時事務(wù)B再去查詢,發(fā)現(xiàn)查詢到前一次不存在的記錄,或者前一次查詢的一些記錄不見了。(事務(wù)B讀取了事務(wù)A新增加的數(shù)據(jù)或者讀不到事務(wù)A刪除的數(shù)據(jù))
臟讀必須杜絕,因為事務(wù)沒有commit。在有些場景下,不可重復(fù)讀和幻讀是可以允許的(事務(wù)已經(jīng)commit),不一定非要杜絕(通過設(shè)置不同的隔離級別解決),由應(yīng)用場景需求決定。
select @@autocommit;
查看MySQL是否自動提交事務(wù)
0表示手動提交事務(wù),1表示自動提交事務(wù),設(shè)置事務(wù)提交方式為手動提交(只影響當(dāng)前session):
以上就是關(guān)于“MySQL事務(wù)的ACID特性及并發(fā)問題怎么解決”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對大家有幫助,若想了解更多相關(guān)的知識內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。