樂觀鎖與悲觀鎖不同的是,它是一種邏輯上的鎖,而不需要資料庫提供鎖機制來支援當資料很重要,回滾或重試一次需要很大的開銷時,需要保證操作的acid性質,
此時應該採用悲觀鎖而當資料對即時的一致性要求不高,重試一次不太影響整體效能時,
可以採用樂觀鎖來保證最終一致性,同時有利於提高併發性通常,
樂觀鎖採用版本號/時間戳的形式實現:給資料額外增加乙個版本號字段進行控制;
更新時,若提交的資料所帶的版本號與當前記錄的版本號一致,則允許變更執行並更新版本號;
若不一致,則意味著產生衝突,根據業務需求直接丟棄並返回失敗,或者嘗試合併在mysql的實踐中,
常見的一種使用樂觀鎖的方法,是在需要使用樂觀鎖的表中,
新增乙個version欄位例如:create table product_amount (id int not null primary key
auto_increment,product_name varchar(64) not null,selling_amount int not null,
storing_amount int not null,version int not null);
當需要更新銷售中的商品數量(selling_amount)時,
使用如下的sql語句:update product_amount set selling_amount = #,
version = # where id=# and version = #;
若該語句返回1,則表示更新成功;若返回0,則表示前後的version不一致,產生衝突,
更新失敗對於更新倉庫中的商品資料(storing_amount)時,也是同理不過,
這樣為每行記錄都統一設定乙個version欄位的樂觀鎖方式,
存在乙個問題:上例中,如果同時需要單獨對selling_amount及storing_amount進行update
(兩條sql語句分別單獨執行),那麼後執行的一條會因為先執行的一條更新了version欄位而失敗,
而這種失敗顯然是沒有必要的,白白浪費了開銷一種比較好的方式是為每個需要樂觀鎖的字段
單獨設定版本號,例如對上例的改造:
create table product_amount (id int not null primary key auto_increment,
product_name varchar(64) not null,selling_amount int not null,
selling_version int not null,storing_amount int not null,
storing_version int not null);
selling_amount和storing_amount分別擁有自己的樂觀鎖版本號
(selling_version和storing_version),更新時分別只關注自己的版本號,
這樣就不會因為版本號被其它字段修改而失敗,提高了併發性
資料庫樂觀鎖
百上千個併發,這樣的情況將導致怎樣的後果。樂觀鎖機制在一定程度上解決了這個問題。樂觀鎖,大多是基於資料版本 version 記錄機制實現。何謂資料版本?即為資料增加乙個版本標識,在基於 資料庫表的版本解決方案中,一般是通過為資料庫表增加乙個 version 欄位來 實現。讀取出資料時,將此版本號一同...
資料庫樂觀鎖
兩個執行緒同時運算元據庫時,希望可以實現,乙個執行緒在修改資料庫的時候,另外乙個執行緒不能對同一條資料進行修改。sql語句 update money set money money 1,version version 1where id and version 測試類 executorservice...
資料庫樂觀鎖
樂觀鎖不是資料庫自帶的,需要我們自己去實現。樂觀鎖是指運算元據庫時 更新操作 想法很樂觀,認為這次的操作不會導致衝突 a使用者操作的時,沒有任何人操作該條記錄 在運算元據時,並不進行任何其他的特殊處理 也就是不加鎖 而在進行更新後,再去判斷是否有衝突了。通常實現是這樣的 在表中的資料進行操作時 更新...