數據庫樂觀鎖

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='用戶信息表';
發佈了199 篇原創文章 · 獲贊 111 · 訪問量 53萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章