一次利用Mysql樂觀鎖實(shí)現(xiàn)的訂單號自增實(shí)現(xiàn)方案

業(yè)務(wù)需求

公司的一個(gè)非高并發(fā)項(xiàng)目中提出了關(guān)于訂單號生成的規(guī)則:
業(yè)務(wù)類型(1位) + 城市編碼(6位) + 渠道(4位) + 年份(4位) + 8位遞增序列號
一共23位

并且需要滿足后8位序列號隨著年份而從1開始循環(huán)切換,即xxxx201900000001...xxxx201900000008 到
xxxx202000000001...xxxx202000000008類似的年切的規(guī)則

技術(shù)分析

基于訂單號生成本身的要求即需要在分布式環(huán)境下保證唯一性授舟,本來想利用redis單線程原子操作來實(shí)現(xiàn)唬复,但是不太好實(shí)現(xiàn)年切的需求候学,因此采用了MySQL樂觀鎖來實(shí)現(xiàn)

樂觀鎖與悲觀鎖

介紹Mysql樂觀鎖之前先簡單說一下樂觀鎖和悲觀鎖的區(qū)別

  • 悲觀鎖

可以理解為悲觀的看待世事悉尾,先假定一定會發(fā)生沖突主儡,每個(gè)線程修改數(shù)據(jù)前都會先獲取鎖暑诸,從而保證同一時(shí)刻只有一個(gè)線程能操作數(shù)據(jù)逗威,從而保證數(shù)據(jù)的完整性峰搪,像Java的Synchronized就可以理解為一種悲觀鎖

  • 樂觀鎖

樂觀的看待世事,每次操作數(shù)據(jù)前都會假定不會有其他人在操作修改數(shù)據(jù)凯旭,等到自己操作完準(zhǔn)備提交更新的時(shí)候判斷一下在此期間是否有其他人已經(jīng)更新了這個(gè)數(shù)據(jù)罢艾,如果沒有人更新過,就直接更新成功尽纽,如果有人更新過咐蚯,就嘗試重新獲取數(shù)據(jù),再操作弄贿,再提交更新春锋,如此循環(huán)

像Java中的atomic類就是一種樂觀鎖的實(shí)現(xiàn),通過CAS實(shí)現(xiàn)(比較并交換)

鎖分類 舉例 應(yīng)用場景
悲觀鎖 Synchronized 并發(fā)寫操作多的場景
樂觀鎖 atomic 讀多寫少的場景

Mysql 樂觀鎖實(shí)現(xiàn)

采用增加字段的形式差凹,如version, timestamp字段

更新時(shí)將version值 + 1期奔, 將timestamp值更新侧馅,并比較該數(shù)據(jù)在數(shù)據(jù)庫中的值是否與自己取出時(shí)的一致,一致則更新成功呐萌,否則就表示已經(jīng)有別人更新了

sql

update table_name set num = #{num}, version = version + 1 where id = 1 and version = #{version}

Mysql 顯示和隱士鎖

我們知道m(xù)ysql的InnoDB采用的是類似兩階段鎖定協(xié)議馁痴,即存在顯示鎖定和隱士鎖定兩種

  • 隱士鎖

當(dāng)我們開啟一個(gè)事務(wù),并執(zhí)行update語句時(shí)肺孤,會鎖定當(dāng)前update條件下的數(shù)據(jù)罗晕,直到commit事務(wù),才會釋放掉這個(gè)隱士鎖

  • 顯示指定鎖

直接利用sql添加鎖

select ... where id = 1 for update

會直接鎖定該條件下的數(shù)據(jù)赠堵,其他事務(wù)再執(zhí)行該條件下數(shù)據(jù)的update操作小渊,只能等以上事務(wù)提交后,釋放鎖以后才行


訂單號生成具體實(shí)現(xiàn)

表結(jié)構(gòu)

用于年切自增序列號維護(hù)表

其中sequence_key column 字段為年切循環(huán)條件茫叭,如'2019'酬屉,'2020'
sequence_id column 字段表示當(dāng)前年切循環(huán)條件下的自增id值

主要sql語句

// 初始化當(dāng)前年切條件自增id數(shù)據(jù)
insert ignore into order_sequence (sequence_id, sequence_key) values(1, #{key});

// 獲取當(dāng)前年切循環(huán)條件下的自增id值
select sequence_id from order_sequence where sequence_key = #{key};

// 樂觀鎖更新當(dāng)前年切循環(huán)條件下的id + 1
update order_sequence set sequence_id = sequence_id + 1 where sequence_key = #{key} and sequence_id = #{sequenceId};

Java代碼實(shí)現(xiàn)

具體編碼細(xì)節(jié)不作展示,這里給出實(shí)現(xiàn)思路

訂單號自增id生成流程

總結(jié)

樂觀鎖的存在并不適合有大量并發(fā)寫的場景揍愁,如果有很多人同時(shí)下單呐萨,并發(fā)更新自增id,就會存在性能問題

其次遞歸方法如果很深莽囤,在性能方面也會存在一定問題

因此谬擦,以上實(shí)現(xiàn)只適合用于并發(fā)量不大的情況,但目前根據(jù)我們的業(yè)務(wù)場景來說時(shí)足夠了烁登,且代碼實(shí)現(xiàn)起來較為簡單,投入成本較低

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蔚舀,一起剝皮案震驚了整個(gè)濱河市饵沧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌赌躺,老刑警劉巖狼牺,帶你破解...
    沈念sama閱讀 221,888評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異礼患,居然都是意外死亡是钥,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評論 3 399
  • 文/潘曉璐 我一進(jìn)店門缅叠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來悄泥,“玉大人,你說我怎么就攤上這事肤粱〉簦” “怎么了?”我有些...
    開封第一講書人閱讀 168,386評論 0 360
  • 文/不壞的土叔 我叫張陵领曼,是天一觀的道長鸥鹉。 經(jīng)常有香客問我蛮穿,道長,這世上最難降的妖魔是什么毁渗? 我笑而不...
    開封第一講書人閱讀 59,726評論 1 297
  • 正文 為了忘掉前任践磅,我火速辦了婚禮,結(jié)果婚禮上灸异,老公的妹妹穿的比我還像新娘府适。我一直安慰自己,他們只是感情好绎狭,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,729評論 6 397
  • 文/花漫 我一把揭開白布细溅。 她就那樣靜靜地躺著,像睡著了一般儡嘶。 火紅的嫁衣襯著肌膚如雪喇聊。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,337評論 1 310
  • 那天蹦狂,我揣著相機(jī)與錄音誓篱,去河邊找鬼。 笑死凯楔,一個(gè)胖子當(dāng)著我的面吹牛窜骄,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播摆屯,決...
    沈念sama閱讀 40,902評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼邻遏,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了虐骑?” 一聲冷哼從身側(cè)響起准验,我...
    開封第一講書人閱讀 39,807評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎廷没,沒想到半個(gè)月后糊饱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,349評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡颠黎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,439評論 3 340
  • 正文 我和宋清朗相戀三年另锋,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片狭归。...
    茶點(diǎn)故事閱讀 40,567評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡夭坪,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出过椎,到底是詐尸還是另有隱情台舱,我是刑警寧澤,帶...
    沈念sama閱讀 36,242評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站竞惋,受9級特大地震影響柜去,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜拆宛,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,933評論 3 334
  • 文/蒙蒙 一嗓奢、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧浑厚,春花似錦职员、人聲如沸二庵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至敢艰,卻和暖如春诬乞,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背钠导。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評論 1 272
  • 我被黑心中介騙來泰國打工震嫉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人牡属。 一個(gè)月前我還...
    沈念sama閱讀 48,995評論 3 377
  • 正文 我出身青樓票堵,卻偏偏與公主長得像,于是被迫代替她去往敵國和親逮栅。 傳聞我的和親對象是個(gè)殘疾皇子悴势,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,585評論 2 359

推薦閱讀更多精彩內(nèi)容