在并發(fā)訪問情況下,很有可能出現(xiàn)不可重復(fù)讀等等讀現(xiàn)象机打。為了更好的應(yīng)對(duì)高并發(fā)矫户,封鎖、時(shí)間戳残邀、樂觀并發(fā)控制(樂觀鎖)皆辽、悲觀并發(fā)控制(悲觀鎖)都是并發(fā)控制采用的主要技術(shù)方式。
鎖分類
①芥挣、按操作劃分:DML鎖膳汪,DDL鎖
②、按鎖的粒度劃分:表級(jí)鎖九秀、行級(jí)鎖、頁(yè)級(jí)鎖
③粘我、按鎖級(jí)別劃分:共享鎖鼓蜒、排他鎖
④痹换、按加鎖方式劃分:自動(dòng)鎖、顯示鎖
⑤都弹、按使用方式劃分:樂觀鎖娇豫、悲觀鎖
樂觀鎖和悲觀鎖
樂觀并發(fā)控制和悲觀并發(fā)控制是并發(fā)控制采用的主要方法。樂觀鎖和悲觀鎖不僅在關(guān)系數(shù)據(jù)庫(kù)里應(yīng)用畅厢,在Hibernate冯痢、Memcache等等也有相關(guān)概念。
悲觀鎖:也即悲觀并發(fā)控制框杜,Pessimistic Concurrency Controller浦楣,縮寫PCC。悲觀鎖是指在數(shù)據(jù)處理過程咪辱,使數(shù)據(jù)處于鎖定狀態(tài)振劳,一般使用數(shù)據(jù)庫(kù)的鎖機(jī)制實(shí)現(xiàn)。
備注油狂,在MySQL中使用悲觀鎖历恐,必須關(guān)閉MySQL的自動(dòng)提交,set autocommit=0专筷。MySQL默認(rèn)使用自動(dòng)提交autocommit模式弱贼,也即你執(zhí)行一個(gè)更新操作,MySQL會(huì)自動(dòng)將結(jié)果提交磷蛹。
//0.開始事務(wù)
begin;/begin work;/start transaction; (三者選一就可
//1.查詢出商品信息
select status from t_goods where id=1 for update;
//2.根據(jù)商品信息生成訂單
insert into t_orders (id,goods_id) values (null,1);
//3.修改商品status為2
update t_goods set status=2;
//4.提交事務(wù)
commit;/commit work;
本例子使用select...for update方式將數(shù)據(jù)鎖住吮旅,也就是開啟了排他鎖
悲觀鎖優(yōu)缺點(diǎn):
悲觀并發(fā)控制(悲觀鎖)采用"先取鎖再分"的保守策略,為數(shù)據(jù)處理提供了安全的保證弦聂。但在效率方面鸟辅,加鎖機(jī)制會(huì)產(chǎn)生額外的開銷,增加產(chǎn)生死鎖的機(jī)會(huì)莺葫。
樂觀鎖:相對(duì)悲觀鎖來說匪凉,樂觀鎖是通過記錄數(shù)據(jù)版本的方式實(shí)現(xiàn)樂觀鎖。為數(shù)據(jù)增加一個(gè)版本標(biāo)識(shí)捺檬,讀取數(shù)據(jù)時(shí)再层,將版本標(biāo)識(shí)一起讀出,數(shù)據(jù)沒更新一次堡纬,就對(duì)版本標(biāo)識(shí)進(jìn)行更新聂受。
樂觀鎖優(yōu)缺點(diǎn):
樂觀鎖認(rèn)為事務(wù)直接競(jìng)爭(zhēng)的概率是很小的,在提交的時(shí)候才鎖定烤镐,所以不會(huì)產(chǎn)生死鎖蛋济。但是如果兩個(gè)事務(wù)同時(shí)讀取數(shù)據(jù)庫(kù)的某一行,這時(shí)炮叶,就會(huì)發(fā)現(xiàn)樂觀鎖的弊端碗旅。
MySQL常用存儲(chǔ)引擎的鎖機(jī)制
BDB:支持頁(yè)級(jí)鎖和表級(jí)鎖渡处,默認(rèn)是頁(yè)級(jí)鎖
InnoDB:支持行級(jí)鎖和表級(jí)鎖,默認(rèn)是行級(jí)鎖
MyISAM &Memory:這兩個(gè)存儲(chǔ)引擎都是采用表級(jí)鎖
MySQL中排它鎖和共享鎖
排它鎖(exclusive locck)
排它鎖又叫寫鎖祟辟,如果事務(wù)T對(duì)A加上排它鎖医瘫,則其它事務(wù)都不能對(duì)A加任何類型的鎖。獲準(zhǔn)排它鎖的事務(wù)既能讀數(shù)據(jù)旧困,又能寫數(shù)據(jù)醇份。
用法:SELECT ... FOR UPDATE
共享鎖(share lock)
共享鎖又叫讀鎖,如果事務(wù)T對(duì)A加上共享鎖吼具,則其它事務(wù)只能對(duì)A再加共享鎖僚纷,不能加其它鎖。獲準(zhǔn)共享鎖的事務(wù)只能讀數(shù)據(jù)馍悟,不能寫數(shù)據(jù)畔濒。
用法:SELECT ... LOCK IN SHARE MODE;
MySQL中的行級(jí)鎖、表級(jí)鎖和頁(yè)級(jí)鎖
行級(jí)鎖:行級(jí)鎖分為共享鎖和排它鎖锣咒。行級(jí)鎖是Mysql中鎖定粒度最細(xì)的鎖侵状。InnoDB引擎支持行級(jí)鎖和表級(jí)鎖,只有在通過索引條件檢索數(shù)據(jù)的時(shí)候毅整,才使用行級(jí)鎖趣兄,否就使用表級(jí)鎖。行級(jí)鎖開銷大悼嫉,加鎖慢艇潭,鎖定粒度最小,發(fā)生鎖沖突概率最低戏蔑,并發(fā)度最高
表級(jí)鎖:表級(jí)鎖分為表共享鎖和表獨(dú)占鎖蹋凝。表級(jí)鎖開銷小,加鎖快总棵,鎖定粒度大鳍寂、發(fā)生鎖沖突最高,并發(fā)度最低
頁(yè)級(jí)鎖:頁(yè)級(jí)鎖是MySQL中鎖定粒度介于行級(jí)鎖和表級(jí)鎖中間的一種鎖情龄。表級(jí)鎖速度快迄汛,但沖突多,行級(jí)沖突少骤视,但速度慢鞍爱。所以取了折衷的頁(yè)級(jí),一次鎖定相鄰的一組記錄专酗。BDB支持頁(yè)級(jí)鎖睹逃。
開銷和加鎖時(shí)間界于表鎖和行鎖之間;會(huì)出現(xiàn)死鎖祷肯;鎖定粒度界于表鎖和行鎖之間唯卖,并發(fā)度一般