1.并發(fā)控制
1.1鎖的類型:
共享鎖(shared lock)也叫讀鎖(read lock)郭蕉,排它鎖(exclusive lock) 也叫寫鎖(write lock),讀鎖是共享的弱匪,相互不阻塞的,而寫鎖是阻塞的,寫鎖的優(yōu)先級(jí)要高于讀鎖聪廉。
1.2鎖的策略:
表鎖:表鎖是Mysql中最基本的鎖的策略,并且是開(kāi)銷最小的策略故慈。當(dāng)用戶對(duì)表進(jìn)行操作的時(shí)候板熊,它會(huì)鎖定整張表。
行鎖:行鎖可以在最大程度上解決并發(fā)問(wèn)題察绷,但是也帶來(lái)了最大的鎖開(kāi)銷干签。
1.3死鎖
死鎖是指兩個(gè)或者多個(gè)事務(wù)在同一資源上相互占用,并請(qǐng)求鎖定對(duì)方占用的資源拆撼,從而導(dǎo)致惡性循環(huán)容劳。當(dāng)多個(gè)事務(wù)試圖以不同的順序鎖定資源的時(shí)候喘沿,就可能產(chǎn)生死鎖,當(dāng)多個(gè)事務(wù)鎖定同一資源的時(shí)候也會(huì)產(chǎn)生死鎖竭贩。
事務(wù)1:
start transaction;
update table set age=45 where id =3;
update table set age=20 where id =4;
commit;
事務(wù)2
start transaction ;
update table set age=13 where id =4;
update table set age=24 where id =3;
commit;
上面這種情況就是典型的死鎖案例蚜印。
1.4多版本并發(fā)控制(*)
上述的鎖是存儲(chǔ)引擎默認(rèn)實(shí)現(xiàn)的,而在真實(shí)的開(kāi)發(fā)環(huán)境中留量,最常用的就是樂(lè)觀鎖和悲觀鎖窄赋,這是兩種問(wèn)題的解決方案。
更新丟失問(wèn)題楼熄,更新丟失問(wèn)題即多個(gè)線程同時(shí)基于同一個(gè)查詢結(jié)果進(jìn)行操作忆绰,后執(zhí)行的操作將先進(jìn)行的操作覆蓋掉了。
+----+--------+------+----- +
| id | name | money| status|
+----+--------+------+----- +
| 1 | 張三 | 1000 | 0 |
+----+--------+------+----- +
假設(shè)需要給張三轉(zhuǎn)賬100元轉(zhuǎn)賬完成后將status設(shè)置為1孝赫,證明已經(jīng)轉(zhuǎn)過(guò)帳就不再執(zhí)行轉(zhuǎn)賬操作较木。
1.select status from order where id =1;//等于0則操作
2.update order set money=money+100 and status=1 where id=1 ;
這時(shí)假如有多個(gè)線程同時(shí)操作這條sql就會(huì)產(chǎn)生上述的丟失更新問(wèn)題。要就解決丟失更新的問(wèn)題有兩種方案青柄。
悲觀鎖(*)
悲觀的認(rèn)為每次操作都會(huì)產(chǎn)生丟失更新問(wèn)題伐债,要使用悲觀鎖策略我們必須進(jìn)行顯式的鎖定,因?yàn)樵趍ysql中默認(rèn)的采用的是autocommit模式致开,也就是說(shuō)如果不是顯式的開(kāi)啟一個(gè)事務(wù)峰锁,則每個(gè)查詢操作都會(huì)當(dāng)作一個(gè)事務(wù)提交。
start transction;
1.select status from order where id =1 for update;//等于0則操作
2.update order set money=money+100 and status=1 where id=1 ;
commit;
此時(shí)mysql會(huì)將id為1的這一行數(shù)據(jù)鎖定双戳,直到更新完成才會(huì)釋放鎖虹蒋。
注意:MySQL InnoDB默認(rèn)Row-Level Lock,但是只有「明確」地指定主鍵飒货,MySQL 才會(huì)執(zhí)行Row lock (只鎖住被選取的數(shù)據(jù)) 魄衅,否則MySQL 將會(huì)執(zhí)行Table Lock (將整個(gè)數(shù)據(jù)表單給鎖住)。
樂(lè)觀鎖(*)
樂(lè)觀的認(rèn)為每次操作不會(huì)產(chǎn)生丟失更新問(wèn)題塘辅,在表中增加一個(gè)版本控制字段進(jìn)行控制晃虫。
update order set money=money+100 and version =version+1 where id=1 and version=0;
樂(lè)觀鎖和悲觀鎖沒(méi)有絕對(duì)的好壞,我們應(yīng)該根據(jù)具體的場(chǎng)景選用不同的解決方式扣墩。
2.事物
事務(wù)的是什么就不做闡述了
2.1事務(wù)的四個(gè)特新(ACID)
- 原子性:一個(gè)事務(wù)必須是一個(gè)不可再分的最小的工作單元哲银,在整個(gè)事務(wù)中操作要么全部成功要么全不成功。
- 一致性: 數(shù)據(jù)庫(kù)總是從一個(gè)一致性狀態(tài)到另一個(gè)一致性狀態(tài)呻惕,最終沒(méi)有提交的數(shù)據(jù)不會(huì)保存到數(shù)據(jù)庫(kù)中荆责。
- 隔離性: 一個(gè)事務(wù)在提交之前對(duì)其他事務(wù)是不可見(jiàn)的
- 持久性: 一旦事務(wù)提交則其修改的數(shù)據(jù)就永久的保存在數(shù)據(jù)庫(kù)中
2.2事務(wù)的隔離級(jí)別
- read uncommited(未提交讀) 會(huì)發(fā)生臟讀
- read commited(提交讀) 可以解決臟讀,可能會(huì)發(fā)生不可重復(fù)讀
- repeatable read (可重復(fù)讀) 會(huì)產(chǎn)生幻讀
- serializable (串行化) 一般不用
2.3Mysql中的事務(wù)
mysql中默認(rèn)的采用的是autocommit模式亚脆,也就是說(shuō)如果不是顯式的開(kāi)啟一個(gè)事務(wù)做院,則每個(gè)查詢操作都會(huì)當(dāng)作一個(gè)事務(wù)提交。可以通過(guò)設(shè)置autocommit開(kāi)啟或者禁用自動(dòng)提交模式山憨。1代表啟用查乒,0代表關(guān)閉。