分布式鎖的三種實現方式

2021-10-25 15:57:50 字數 3067 閱讀 8327

更多請參考:

1、基於資料庫的實現方式的核心思想是:在資料庫中建立乙個表,表中包含方法名等字段,並在方法名字段上建立唯一索引,想要執行某個方法,就使用這個方法名向表中插入資料,成功插入則獲取鎖,執行完成後刪除對應的行資料釋放鎖。

drop table if exists `method_lock`;

create table `method_lock` (

`id` int(11) unsigned not null auto_increment comment '主鍵',

`method_name` varchar(64) not null comment '鎖定的方法名',

`desc` varchar(255) not null comment '備註資訊',

`update_time` timestamp not null default current_timestamp on update current_timestamp,

primary key (`id`),

unique key `uidx_method_name` (`method_name`) using btree

) engine=innodb auto_increment=3 default charset=utf8 comment='鎖定中的方法';

2、想要執行某個方法,就使用這個方法名向表中插入資料:

insert into method_lock (method_name, desc) values ('methodname', '測試的methodname');
因為我們對method_name做了唯一性約束,這裡如果有多個請求同時提交到資料庫的話,資料庫會保證只有乙個操作可以成功,那麼我們就可以認為操作成功的那個執行緒獲得了該方法的鎖,可以執行方法體內容。

3、成功插入則獲取鎖,執行完成後刪除對應的行資料釋放鎖:

delete from method_lock where method_name ='methodname';
1、選用redis實現分布式鎖原因:

(1)redis有很高的效能;

(2)redis命令對此支援較好,實現起來比較方便

2、使用命令介紹:

在使用redis實現分布式鎖的時候,主要就會使用到這三個命令。

3、實現思想:

4、分布式鎖的簡單實現** (秒殺系統)

/**

* 分布式鎖的簡單實現**

* created by liuyang on 2017/4/20.

*/public class distributedlock

/*** 加鎖

* @param lockname 鎖的key

* @param acquiretimeout 獲取超時時間

* @param timeout 鎖的超時時間

* @return 鎖標識

*/public string lockwithtimeout(string lockname, long acquiretimeout, long timeout)

// 返回-1代表key沒有設定超時時間,為key設定乙個超時時間

if (conn.ttl(lockkey) == -1)

try catch (interruptedexception e)

}} catch (jedi***ception e) finally

}return retidentifier;

}/**

* 釋放鎖

* @param lockname 鎖的key

* @param identifier 釋放鎖的標識

* @return

*/public boolean releaselock(string lockname, string identifier)

retflag = true;

}conn.unwatch();

break;

}} catch (jedi***ception e) finally

}return retflag;

}}

5、測試剛才實現的分布式鎖

例子中使用50個執行緒模擬秒殺乙個商品,使用–運算子來實現商品減少,從結果有序性就可以看出是否為加鎖狀態。

模擬秒殺服務,在其中配置了jedis執行緒池,在初始化的時候傳給分布式鎖,供其使用。

/**

* created by liuyang on 2017/4/20.

*/public class service

public void seckill()

}

public class threada extends thread 

@override

public void run()

}public class test

}}

zookeeper是乙個為分布式應用提供一致性服務的開源元件,它內部是乙個分層的檔案系統目錄樹結構,規定同乙個目錄下只能有乙個唯一檔名。基於zookeeper實現分布式鎖的步驟如下:

(1)建立乙個目錄mylock;

(2)執行緒a想獲取鎖就在mylock目錄下建立臨時順序節點;

(3)獲取mylock目錄下所有的子節點,然後獲取比自己小的兄弟節點,如果不存在,則說明當前執行緒順序號最小,獲得鎖;

(4)執行緒b獲取所有節點,判斷自己不是最小節點,設定監聽比自己次小的節點;

(5)執行緒a處理完,刪除自己的節點,執行緒b監聽到變更事件,判斷自己是不是最小的節點,如果是則獲得鎖。

這裡推薦乙個apache的開源庫curator,它是乙個zookeeper客戶端,curator提供的interprocessmutex是分布式鎖的實現,acquire方法用於獲取鎖,release方法用於釋放鎖。

優點:具備高可用、可重入、阻塞鎖特性,可解決失效死鎖問題。

缺點:因為需要頻繁的建立和刪除節點,效能上不如redis方式。

實現分布式鎖的三種方式

1 資料庫的樂觀鎖 版本號機制 悲觀鎖與樂觀鎖 2 基於redis的分布式鎖 加鎖public class redistool return false 我們加鎖就一行 jedis.set string key,string value,string n string expx,int time 這...

實現分布式鎖的三種方式

類似的文章網上一搜一大把,實現方式也無非這三種,不過自己還是總結一下吧,實際應用中只採用過快取來實現 通過增刪操作,借助資料庫唯一索引的唯一性或主鍵唯一性,來實現 缺點 資料庫單點問題,如果資料庫掛了,會導致業務系統不可用 獲取鎖後,沒有失效時間,如果解鎖失敗,就會導致鎖記錄始終在資料庫中,其他執行...

實現分布式鎖的三種方式

類似的文章網上一搜一大把,實現方式也無非這三種,不過自己還是總結一下吧,實際應用中只採用過快取來實現 通過增刪操作,借助資料庫唯一索引的唯一性或主鍵唯一性,來實現 缺點 資料庫單點問題,如果資料庫掛了,會導致業務系統不可用 獲取鎖後,沒有失效時間,如果解鎖失敗,就會導致鎖記錄始終在資料庫中,其他執行...