0 概述
在實際工作中,經常遇到對某一張表某一列進行更新操作,由於在分佈式環境下高併發環境下是很容易出現問題。本文主要講述採用樂觀鎖來解決這一問題。樂觀鎖的基本設計思想來至Java裏的CompareAndSet(CAS)。
1 實例分析
如下下面這張表,假設小紅會員積分爲2分,由於小紅在線時間比較長現在積分變成4。因此需要更新小紅積分爲4,更新方式如下,然而這種情況在分佈式系統環境中可能會出現問題。
update User set memberPoint=4 where id=1;
CREATE TABLE `User` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`userName` varchar(20) NOT NULL COMMENT '用戶名',
`memberPoint` int(11) NOT NULL COMMENT '會員積分(最大是10分)',
`isDeleted` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '是否刪除,0:否嗎,1:是',
`created` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '創建時間',
`updated` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '更新時間',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用戶信息表';
採用樂觀鎖實現原子更新,每一次更新時候都要判斷版本號
1.更新之前首先查詢出這條用戶信息
2.獲取到version&memberPoint等信息
3.根據規則計算現在積分爲4
4.採用樂觀鎖更新
5.更新失敗可以回到step 1繼續執行(重試)
update User set memberPoint=4,version=version+1 where id=1 and version=0
CREATE TABLE `User` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`userName` varchar(20) NOT NULL COMMENT '用戶名',
`memberPoint` int(11) NOT NULL COMMENT '會員積分',
`version` int(11) NOT NULL COMMENT '樂觀鎖',
`created` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '創建時間',
`updated` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '更新時間',
`isDeleted` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '是否刪除,0:否嗎,1:是',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='用戶信息表';