跳到主要內容

Race condition 競爭危害

通常在課本裡常舉例存錢並匯款

帳戶裡有80元
如果我同時匯款20,存款20
會有什麼狀況呢

正常來說帳戶裡應該還是80元,
因為自然人無法同時存款及匯款。

你可以叫你的朋友幫忙,你去存款時,同分同秒同微秒看會不會發生什麼事 XD

而電腦是怎麼看待這件事的呢
如果在同一時間下

1我要匯款會先取讀我現在有多少錢,並扣款變60,再匯出。
2問題來了,我同時存款20,我應該要讀到60元才是正確的,但因為同時間做,所以電腦讀到了80元,再存20,即100元。

如果這世界都這樣,大家都變有錢人了。
如同小刀所說:你的錢就是我的錢,我的錢就是你的錢,發財啦!


這就是一個競時的問題
在微軟的網站上有提出11點競爭問題
http://support.microsoft.com/kb/317723/zh-tw


這裡我只提Database

我們可以使用select … for update的語法來保護自己的交易

START TRANSACTION;
SELECT quantity FROM product WHERE product_id = 5 FOR UPDATE;
UPDATE product SET quantity = quantity - 1 WHERE product_id = 5;
COMMIT;

這裡舉的例子是,每當在交易時,會查尋數量,後再-1更新(實際上的語法會更多,例 大於零才扣庫存等…)

在MYSQL資料庫,只有Storage Engine 是 InnoDB 的情形下才有作用,且需要等查詢連線COMMIT後才可以做其他動作。
而 PostgreSQL 似乎其他連線還可以執行SELECT查詢。

以上是悲觀鎖定


以前做過樂觀鎖定,但現在CPU Thread 愈來愈多的情形下(不知道是不是這樣,但好像是),好像都無法太樂觀…

常觀測到的結果,都還剩一個品項結果還是多賣了一個。
我們預想的是

如果兩個人同時買一張票或一張票(房)且cpu還是會有處理上的差異(微秒之間)
正常來說
a買一張
b買一張

還剩一張

a先買 扣完 b查不到後,售完。

但往往是這樣

a先買 扣完 b還是查到一張,b再買,因為寫入剩於數質都是0 所以 ab 都買成了…

所以之後會再檢查是否過量count 所有買票的筆數,還是等於開放的筆數…

為什麼!! 可能b寫入太慢,或資料庫動作太慢…

不然也是有檢查,數量小於0,兩張都不成功,反正樂觀鎖定不Work就是了…
(ps:使用機器人狂買所測出的結果,實際上真的還是發生了)






留言

這個網誌中的熱門文章

一個上帝、狼、獅子和羊的故事

上帝把兩群羊放在草原上,一群在南,一群在北。 上帝還給羊群找了兩種天敵,一種是獅子,一種是狼。 上帝對羊群說:「如果你們要狼,就給一隻,任由牠隨意地咬你們,但狼比獅子瘦弱且食量少。 如果你們要獅子,就給兩頭,但你們可以在兩頭獅子中任選一頭,而且還可以隨時更換。」 這道即將考驗你的問題,就是「如果你也在羊群中,你是選狼呢?還是選獅子?」 依照你的直覺,應該很容易選擇吧?很好!現在起,務必牢牢地記住你的選擇,然後往下接著看。 南邊那群羊想了想,獅子比狼兇猛得多,還是要狼吧!於是,牠們就要了一隻狼。 北邊那群羊則想,獅子雖然比狼兇猛得多,但我們有選擇權,還是要獅子吧!於是,牠們就要了兩頭獅子。 那隻進了南邊羊群的狼,即刻開始吃羊。狼身體小,食量也小,一隻羊夠牠吃幾天了, 如此羊群幾天才被追殺一次。北邊那群羊挑選了一頭獅子,另一頭則留在上帝那裡。 而進入北邊羊群後的獅子,不但比狼兇猛,而且食量驚人,才開始吃羊, 就每天至少吃一隻羊,所以羊群天天都驚恐萬狀地被追殺。北邊的羊群趕緊請上帝換一頭獅子。 不料,上帝保管的那頭獅子太久沒吃,正飢餓難耐,牠撲進羊群,比前面那頭獅子咬得更瘋狂。 羊群一天到晚只是逃命,連草都快吃不成了。 南邊的羊群慶幸自己選對了天敵,又嘲笑北邊的羊群沒有眼光。 北邊的羊群非常後悔,向上帝大倒苦水,要求更換天敵,改要一隻狼。 上帝說:「天敵一旦確定,就不能更改,必須世代相隨。請認清現實,你們唯一的權利,是在兩頭獅子中做選擇。」 北邊的羊群只好把兩頭獅子不斷更換。 可是兩頭獅子同樣凶殘,換哪一頭都讓北邊的羊群比南邊的羊群悲慘得多,牠們索性不換了, 讓一頭獅子吃得膘肥體壯,另一頭獅子則餓得精瘦。眼看那頭瘦獅子快要餓死了,羊群才請上帝換一頭。 這頭瘦獅子經過長時間的飢餓後,慢慢悟出了一個道理──自己雖然兇猛異常,一百隻羊都不是對手, 可是自己的命運卻操縱在羊群手裡,羊群隨時可以把自己送回上帝那裡,讓自己飽受飢餓的煎熬,甚至有可能餓死── 想通這個道理後,瘦獅子就對羊群特別客氣,只吃死羊和病羊,凡是健康的羊牠都不吃,令羊群喜出望外。 所以有幾隻小羊開心地提議:「乾脆固定只要瘦獅子,不要肥獅子。怎樣!?」 一隻老公羊馬上提醒:「別忘啦!瘦獅子是怕我們送牠回上帝那裡挨餓,才對我們這麼好。 萬一餓死了肥獅子,我們將...

透過 Docker 快速建立 openvpn 伺服器

此docker install安裝適用 ubuntu 16.04 18.04 如果已安裝docker-compose 那任何linux環境都可以使用 sudo apt update && sudo apt install -y curl vim curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh sudo adduser   "$USER"   docker sudo reboot 然後再登入一次 接下來有安裝docker-compose 的機器都適用 nano docker-compose.yml OR vi docker-compose.yml -------請輸入以下內容 services:     openvpn:         container_name: openvpn         image: kylemanna/openvpn         volumes:         - ./data:/etc/openvpn         devices:         - /dev/net/tun         ports:         - '1194:1194/udp'         cap_add:         - NET_ADMIN         restart: always         sysctls:           net.ipv6.conf.all.disable_ipv6: 0       ...

完美同盟/Perfect League

完美同盟/Perfect League 時間  20-30MIN 人數  4 OR 6人 年齡  6歲以上 類型  卡牌 機制  Co-operative Play 合作遊戲、Hand Management 手牌管理、Memory 記憶、Trick-taking 牌組搭配 設計師  Way Of Change、ALex Tseng 美術  Tanner Lai 編輯  Bountiful Living 出版年 2016 遊戲基本介紹 想認識新朋友 (異性朋友),不可或缺的必備良藥! 3回合內玩出默契與互動,兩人一組充足的互動特性,讓原本尷尬與陌生的新朋友變的熱絡,在遊戲回合後自然而然讓兩人有更多的討論。 遊戲規則介紹 這是一款兩個人一組的默契遊戲,經由與隊友交換手牌,組合桌上公牌,搭配出最大牌型決勝負。遊戲過程主要是選牌(宣告)、交換手牌、出牌、組合牌型 四個步驟來進行,反覆直到有隊伍取得10分獲勝。 [ 準備階段 ] 4人遊戲時,先將特殊牌(花朵圖案)挑出,然後每人發11張手牌及2張特殊牌,同組玩家對坐且左右兩邊為其他Team的玩家 [ 回合開始 ] 回合開始時在場上開啟三張公用牌 [ 宣告(選牌) ] 參考桌上公牌,思考最佳牌組組合,起始玩家及起始玩家右手邊的玩家,需要選擇要選2張或是1張公牌來組合牌型,被選過的牌,另一隊也可以選擇。 [ 交換手牌 ] 選擇1張公牌的隊伍可以跟同伴交換3張手牌,選擇2張的隊伍只能交換1張手牌,藉由交換手牌暗示隊友如何出牌,過程不可提示牌組相關的訊息。(註:特殊牌不能交換) [ 出牌 ] 從起始玩家開始,順時針每人輪流出1張牌,每人需出2張牌,與隊友在桌上選好的公牌搭配(選2張的隊伍,可以選1張或2張公牌組合),組合成最大的5張牌牌組與敵隊比大,結算後含公牌(不含手牌)放入棄牌堆。 [ 結算 ] 每回合獲勝隊伍會得到2顆鑽石,第二名會得到1顆,1顆鑽石代表1分,紅寶石代表5分,可自行決定達標獲勝總分,培養最佳默契。(註:使用剩餘的牌繼續下一回合遊戲,最後剩3張(含特殊牌)遊戲結束。) 遊戲特別之處 1.只要10分鐘,將尷尬化為無形,就是這個遊戲最強的特別之處! 2.利用交換手牌加深...