分布式鎖的實(shí)現(xiàn)方式之一:數(shù)據(jù)庫(kù)實(shí)現(xiàn)

一. 為什么要使用分布式鎖

Q: 在同一個(gè)JVM進(jìn)程內(nèi),多線程并發(fā)的情況下解虱,如果保證一個(gè)代碼塊在同一時(shí)間只能由一個(gè)線程訪問(wèn)?
A: 用【鎖】來(lái)保證悍汛,比如java的synchronized語(yǔ)法,以及Reentrantlock類等等


image.png

Q: 如果在分布式的集群環(huán)境中,如何保證不同節(jié)點(diǎn)的線程同步執(zhí)行呢术陶?
A: ?


image.png

???????為了保證一個(gè)方法或?qū)傩栽诟卟l(fā)情況下的同一時(shí)間只能被同一個(gè)線程執(zhí)行接谨,在傳統(tǒng)單體應(yīng)用單機(jī)部署的情況下,可以使用Java并發(fā)處理相關(guān)的API(如ReentrantLock或Synchronized)進(jìn)行互斥控制锅睛。在單機(jī)環(huán)境中辣垒,Java中提供了很多并發(fā)處理相關(guān)的API勋桶。但是,隨著業(yè)務(wù)發(fā)展的需要侥猬,原單體單機(jī)部署的系統(tǒng)被演化成分布式集群系統(tǒng)后例驹,由于分布式系統(tǒng)多線程、多進(jìn)程并且分布在不同機(jī)器上退唠,這將使原單機(jī)部署情況下的并發(fā)控制鎖策略失效鹃锈,單純的Java API并不能提供分布式鎖的能力。為了解決這個(gè)問(wèn)題就需要一種跨JVM的互斥機(jī)制來(lái)控制共享資源的訪問(wèn)瞧预,這就是分布式鎖要解決的問(wèn)題屎债!
??

二. 分布式鎖的特點(diǎn)

?????1.可以保證在分布式部署的應(yīng)用集群中,同一個(gè)方法在同一時(shí)間只能被一臺(tái)機(jī)器上的一個(gè)線程執(zhí)行垢油。
?????2.這把鎖要是一把可重入鎖(避免死鎖)
?????3.這把鎖最好是一把阻塞鎖(根據(jù)業(yè)務(wù)需要)
?????4.有高可用的獲取鎖和釋放鎖的功能
?????5.獲取鎖和釋放鎖的性能要好
??

三. 分布式鎖的三種實(shí)現(xiàn)

1.基于數(shù)據(jù)庫(kù)實(shí)現(xiàn)分布式鎖

?????要實(shí)現(xiàn)分布式鎖盆驹,最簡(jiǎn)單的方式可能就是直接創(chuàng)建一張鎖表,然后通過(guò)操作該表中的數(shù)據(jù)來(lái)實(shí)現(xiàn)了滩愁。
?????當(dāng)我們要鎖住某個(gè)方法或資源時(shí)躯喇,我們就在該表中增加一條記錄,想要釋放鎖的時(shí)候就刪除這條記錄硝枉。
?????創(chuàng)建這樣一張數(shù)據(jù)庫(kù)表:

CREATE TABLE `methodLock` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵',
  `method_name` varchar(64) NOT NULL DEFAULT '' COMMENT '鎖定的方法名',
  `desc` varchar(1024) NOT NULL DEFAULT '備注信息',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '保存數(shù)據(jù)時(shí)間玖瘸,自動(dòng)生成',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uidx_method_name` (`method_name `) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='鎖定中的方法';

當(dāng)我們想要鎖住某個(gè)方法時(shí),執(zhí)行以下SQL:

insert into methodLock(method_name,desc) values (‘method_name’,‘desc’)

?????因?yàn)槲覀儗?duì)method_name做了唯一性約束檀咙,這里如果有多個(gè)請(qǐng)求同時(shí)提交到數(shù)據(jù)庫(kù)的話雅倒,數(shù)據(jù)庫(kù)會(huì)保證只有一個(gè)操作可以成功,那么我們就可以認(rèn)為操作成功的那個(gè)線程獲得了該方法的鎖弧可,可以執(zhí)行方法體內(nèi)容蔑匣。
?????當(dāng)方法執(zhí)行完畢之后劣欢,想要釋放鎖的話,需要執(zhí)行以下Sql:

delete from methodLock where method_name ='method_name'

上面這種簡(jiǎn)單的實(shí)現(xiàn)有以下幾個(gè)問(wèn)題:

1裁良、這把鎖強(qiáng)依賴數(shù)據(jù)庫(kù)的可用性凿将,數(shù)據(jù)庫(kù)是一個(gè)單點(diǎn),一旦數(shù)據(jù)庫(kù)掛掉价脾,會(huì)導(dǎo)致業(yè)務(wù)系統(tǒng)不可用牧抵。
2、這把鎖沒有失效時(shí)間侨把,一旦解鎖操作失敗犀变,就會(huì)導(dǎo)致鎖記錄一直在數(shù)據(jù)庫(kù)中,其他線程無(wú)法再獲得到鎖秋柄。
3获枝、這把鎖只能是非阻塞的,因?yàn)閿?shù)據(jù)的insert操作骇笔,一旦插入失敗就會(huì)直接報(bào)錯(cuò)省店。沒有獲得鎖的線程并不會(huì)進(jìn)入排隊(duì)隊(duì)列,要想再次獲得鎖就要再次觸發(fā)獲得鎖操作笨触。
4懦傍、這把鎖是非重入的,同一個(gè)線程在沒有釋放鎖之前無(wú)法再次獲得該鎖芦劣。因?yàn)閿?shù)據(jù)中數(shù)據(jù)已經(jīng)存在了粗俱。

當(dāng)然,我們也可以有其他方式解決上面的問(wèn)題持寄。
1.數(shù)據(jù)庫(kù)是單點(diǎn)源梭?搞兩個(gè)數(shù)據(jù)庫(kù),數(shù)據(jù)之前雙向同步稍味。一旦掛掉快速切換到備庫(kù)上废麻。
2.沒有失效時(shí)間?只要做一個(gè)定時(shí)任務(wù)模庐,每隔一定時(shí)間把數(shù)據(jù)庫(kù)中的超時(shí)數(shù)據(jù)清理一遍掂碱。
3.非阻塞的沧卢?搞一個(gè)while循環(huán)披诗,直到insert成功再返回成功唱歧。
4.非重入的颅崩?在數(shù)據(jù)庫(kù)表中加個(gè)字段孩革,記錄當(dāng)前獲得鎖的機(jī)器的主機(jī)信息和線程信息锅移,那么下次再獲取鎖的時(shí)候先查詢數(shù)據(jù)庫(kù),如果當(dāng)前機(jī)器的主機(jī)信息和線程信息在數(shù)據(jù)庫(kù)可以查到的話,直接把鎖分配給他就可以了。

??
參考文章:
1.https://www.hollischuang.com/archives/1716
2.https://blog.csdn.net/xlgen157387/article/details/79036337
3.https://juejin.im/post/5b037d5c518825426e024473

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末他挎,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子贸街,更是在濱河造成了極大的恐慌逸尖,老刑警劉巖娇跟,帶你破解...
    沈念sama閱讀 217,907評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異太颤,居然都是意外死亡苞俘,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門龄章,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)吃谣,“玉大人,你說(shuō)我怎么就攤上這事做裙「诒铮” “怎么了?”我有些...
    開封第一講書人閱讀 164,298評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵锚贱,是天一觀的道長(zhǎng)仔戈。 經(jīng)常有香客問(wèn)我,道長(zhǎng)拧廊,這世上最難降的妖魔是什么监徘? 我笑而不...
    開封第一講書人閱讀 58,586評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮吧碾,結(jié)果婚禮上凰盔,老公的妹妹穿的比我還像新娘。我一直安慰自己滤港,他們只是感情好廊蜒,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著溅漾,像睡著了一般山叮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上添履,一...
    開封第一講書人閱讀 51,488評(píng)論 1 302
  • 那天屁倔,我揣著相機(jī)與錄音,去河邊找鬼暮胧。 笑死锐借,一個(gè)胖子當(dāng)著我的面吹牛问麸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播钞翔,決...
    沈念sama閱讀 40,275評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼严卖,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了布轿?” 一聲冷哼從身側(cè)響起哮笆,我...
    開封第一講書人閱讀 39,176評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎汰扭,沒想到半個(gè)月后稠肘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,619評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡萝毛,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評(píng)論 3 336
  • 正文 我和宋清朗相戀三年项阴,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片笆包。...
    茶點(diǎn)故事閱讀 39,932評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡环揽,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出色查,到底是詐尸還是另有隱情撞芍,我是刑警寧澤序无,帶...
    沈念sama閱讀 35,655評(píng)論 5 346
  • 正文 年R本政府宣布晶通,位于F島的核電站狮辽,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏树叽。R本人自食惡果不足惜题诵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評(píng)論 3 329
  • 文/蒙蒙 一性锭、第九天 我趴在偏房一處隱蔽的房頂上張望祭椰。 院中可真熱鬧方淤,春花似錦携茂、人聲如沸讳苦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蠕趁。三九已至豁延,卻和暖如春诱咏,著一層夾襖步出監(jiān)牢的瞬間胰苏,已是汗流浹背硕并。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人么库。 一個(gè)月前我還...
    沈念sama閱讀 48,095評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親怜校。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評(píng)論 2 354

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