1. 程式人生 > >mysql數據庫怎麽設置樂觀鎖

mysql數據庫怎麽設置樂觀鎖

reat 比較 sql語句 blog 悲觀鎖 class product 數量 pre

樂觀鎖與悲觀鎖不同的是,它是一種邏輯上的鎖,而不需要數據庫提供鎖機制來支持當數據很重要,
回滾或重試一次需要很大的開銷時,需要保證操作的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 = #{selling_amount},
version = #{new_version} where id=#{id} and version = #{old_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),更新時分別只關註自己的版本號,
這樣就不會因為版本號被其它字段修改而失敗,提高了並發性

mysql數據庫怎麽設置樂觀鎖