mysql事務(wù)

事務(wù)的四個(gè)特征(ACID)

  1. 原子性(atomicity):一個(gè)事務(wù)必須視為一個(gè)不可分割的最小工作單元,整個(gè)事務(wù)中的所有操作要么全部提交成功,要么全部失敗回滾,對(duì)于一個(gè)事務(wù)來(lái)說(shuō),不可能只執(zhí)行其中的一部分操作,這就是事務(wù)的原子性。
  2. 一致性(consistency):數(shù)據(jù)庫(kù)總數(shù)從一個(gè)一致性的狀態(tài)轉(zhuǎn)換到另一個(gè)一致性的狀態(tài)。
  3. 隔離性(isolation):一個(gè)事務(wù)所做的修改在最終提交以前,對(duì)其他事務(wù)是不可見(jiàn)的。
  4. 持久性(durability):一旦事務(wù)提交,則其所做的修改就會(huì)永久保存到數(shù)據(jù)庫(kù)中。此時(shí)即使系統(tǒng)崩潰,修改的數(shù)據(jù)也不會(huì)丟失。

事務(wù)的隔離級(jí)別

不可重復(fù)讀"意味著,在數(shù)據(jù)庫(kù)訪問(wèn)中,一個(gè)事務(wù)范圍內(nèi)兩個(gè)相同的查詢卻返回了不同數(shù)據(jù)。這是由于查詢時(shí)系統(tǒng)中其他事務(wù)修改的提交而引起的。 例如:事務(wù)B中對(duì)某個(gè)查詢執(zhí)行兩次,當(dāng)?shù)谝淮螆?zhí)行完時(shí),事務(wù)A對(duì)其數(shù)據(jù)進(jìn)行了修改。事務(wù)B中再次查詢時(shí),數(shù)據(jù)發(fā)生了改變

臟讀意味著一個(gè)事務(wù)讀取了另一個(gè)事務(wù)未提交的數(shù)據(jù),而這個(gè)數(shù)據(jù)是有可能回滾的。

幻讀是指當(dāng)事務(wù)不是獨(dú)立執(zhí)行時(shí)發(fā)生的一種現(xiàn)象,例如第一個(gè)事務(wù)對(duì)一個(gè)表中的數(shù)據(jù)進(jìn)行了修改,這種修改涉及到表中的全部數(shù)據(jù)行。同時(shí),第二個(gè)事務(wù)也修改這個(gè)表中的數(shù)據(jù),這種修改是向表中插入一行新數(shù)據(jù)。那么,以后就會(huì)發(fā)生操作第一個(gè)事務(wù)的用戶發(fā)現(xiàn)表中還有沒(méi)有修改的數(shù)據(jù)行,就好象發(fā)生了幻覺(jué)一樣。

  1. 讀未提交(Read uncommited)
    在該隔離級(jí)別,所有事務(wù)都可以看到其他未提交事務(wù)的執(zhí)行結(jié)果。本隔離級(jí)別很少用于實(shí)際應(yīng)用,因?yàn)樗男阅芤膊槐绕渌?jí)別好多少。除非有特殊的應(yīng)用場(chǎng)景,在一般應(yīng)用中很少使用。
  2. 讀已提交(Read Committed)
    這是大多數(shù)數(shù)據(jù)庫(kù)系統(tǒng)的默認(rèn)隔離級(jí)別(但不是MySQL默認(rèn)的)。它滿足了隔離的簡(jiǎn)單定義:一個(gè)事務(wù)只能看見(jiàn)已經(jīng)提交事務(wù)所做的改變。
  3. 可重復(fù)讀(Repeatable Read)
    這是MySQL的默認(rèn)事務(wù)隔離級(jí)別,它確保同一事務(wù)的多個(gè)實(shí)例在并發(fā)讀取數(shù)據(jù)時(shí),會(huì)看到同樣的數(shù)據(jù)行。
  4. 可串行化(Serializable)
    這是最高的隔離級(jí)別,它通過(guò)強(qiáng)制事務(wù)排序,使之不可能相互沖突,從而解決幻讀問(wèn)題。簡(jiǎn)言之,它是在每個(gè)讀的數(shù)據(jù)行上加上共享鎖。在這個(gè)級(jí)別,可能導(dǎo)致大量的超時(shí)現(xiàn)象和鎖競(jìng)爭(zhēng)。

四個(gè)隔離級(jí)別可能出現(xiàn)的問(wèn)題:

四個(gè)隔離級(jí)別可能出現(xiàn)的問(wèn)題

悲觀鎖和樂(lè)觀鎖

悲觀鎖:顧名思義,就是很悲觀,每次去拿數(shù)據(jù)的時(shí)候都認(rèn)為別人會(huì)修改,所以每次在拿數(shù)據(jù)的時(shí)候都會(huì)上鎖,這樣別人想拿這個(gè)數(shù)據(jù)就會(huì)block直到它拿到鎖。
樂(lè)觀鎖:顧名思義,就是很樂(lè)觀,每次去拿數(shù)據(jù)的時(shí)候都認(rèn)為別人不會(huì)修改,所以不會(huì)上鎖,但是在更新的時(shí)候會(huì)判斷一下在此期間別人有沒(méi)有去更新這個(gè)數(shù)據(jù),可以使用版本號(hào)等機(jī)制。

悲觀鎖和樂(lè)觀鎖本質(zhì)區(qū)別在于,一個(gè)對(duì)象被加鎖,悲觀鎖是發(fā)現(xiàn)對(duì)象被加鎖,直接切換上下文,等待對(duì)象解鎖通知;而樂(lè)觀鎖不切換上下文,在那自旋,隔段時(shí)間主動(dòng)詢問(wèn)是否解鎖;

使用場(chǎng)景
悲觀鎖適用于并發(fā)爭(zhēng)搶比較嚴(yán)重的場(chǎng)景;
使用

select * from table where id = 1;

可實(shí)現(xiàn)悲觀鎖;

樂(lè)觀鎖使用于并發(fā)爭(zhēng)搶不太嚴(yán)重的場(chǎng)景;
使用

update table set name = #{test},version = version+1 where id = #{id} and version = #{version}

可實(shí)現(xiàn)樂(lè)觀鎖;

事務(wù)調(diào)優(yōu)原則

  1. 減少鎖的覆蓋范圍
    myisam表鎖--->Innodb行鎖
    原位鎖(排他鎖、讀寫(xiě)鎖)--->MVCC多版本
  2. 增加鎖上課并行的線程數(shù)
    讀寫(xiě)分離,允許并發(fā)讀取數(shù)據(jù);可使用ReadWriteLock讀寫(xiě)鎖
  3. 選擇正確的鎖類(lèi)型
    悲觀鎖和樂(lè)觀鎖

MVCC多版本
待續(xù)~~~
切換上下文

目前流行的CPU在同一時(shí)間內(nèi)只能運(yùn)行一個(gè)線程,超線程的處理器可以在同一時(shí)間運(yùn)行多個(gè)線程(包括多核CPU),Linux內(nèi)核會(huì)把多核的處理器當(dāng)作多個(gè)單獨(dú)的CPU來(lái)識(shí)別。   
一個(gè)標(biāo)準(zhǔn)的Linux內(nèi)核可以支持運(yùn)行50~50000個(gè)進(jìn)程運(yùn)行,對(duì)于普通的CPU,內(nèi)核會(huì)調(diào)度和執(zhí)行這些進(jìn)程。每個(gè)進(jìn)程都會(huì)分到CPU的時(shí)間片來(lái)運(yùn)行,當(dāng)一個(gè)進(jìn)程用完時(shí)間片或者被更高優(yōu)先級(jí)的進(jìn)程搶占后,它會(huì)備份到CPU的運(yùn)行隊(duì)列中,同時(shí)其他進(jìn)程在CPU上運(yùn)行。這個(gè)進(jìn)程切換的過(guò)程被稱(chēng)作上下文切換。過(guò)多的上下文切換會(huì)造成系統(tǒng)很大的開(kāi)銷(xiāo)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容