鐢变簬鏁版嵁閲忕殑宸ㄥぇ锛屽ぇ閮ㄥ垎Web搴旂敤閮介渶瑕侀儴缃插緢澶氫釜鏁版嵁搴撳疄渚嬨€傝繖鏍凤紝鏈変簺鐢ㄦ埛鎿嶄綔灏卞彲鑳介渶瑕佸幓淇敼澶氫釜鏁版嵁搴撳疄渚嬩腑鐨勬暟鎹€備紶缁熺殑瑙e喅鏂规硶鏄娇鐢ㄥ垎甯冨紡浜嬪姟淇濊瘉鏁版嵁鐨勫叏灞€涓€鑷存€э紝缁忓吀鐨勬柟娉曟槸浣跨敤涓ら樁娈垫彁浜ゅ崗璁€?br>
闀挎湡浠ユ潵锛屽垎甯冨紡浜嬪姟鎻愪緵鐨勪紭闆呯殑鍏ㄥ眬ACID淇濊瘉楹婚唹浜嗗簲鐢ㄥ紑鍙戣€呯殑蹇冪伒锛屽緢澶氫汉閮戒笉鏁㈣秺闆锋睜涓€姝ワ紝鎯冲儚娌℃湁鍒嗗竷寮忎簨鍔$殑涓栫晫浼氭槸鎬庢牱銆傚浠婂氨濡侻ySQL鍜孭ostgreSQL杩欑被闈㈠悜浣庣鐢ㄦ埛鐨勫紑婧愭暟鎹簱閮芥敮鎸佸垎甯冨紡浜嬪姟浜嗭紝寮€鍙戣€呮洿鏄矇閱夊叾涓紝涓嶅幓鑰冭檻鍒嗗竷寮忎簨鍔℃槸鍚︾粰绯荤粺甯︽潵浜嗕激瀹炽€?br>
浜嬪疄涓婏紝鏈夋墍寰楀繀鏈夋墍澶憋紝鍒嗗竷寮忎簨鍔℃彁渚涚殑ACID淇濊瘉鏄互鎹熷绯荤粺鐨勫彲鐢ㄦ€с€佹€ц兘涓庡彲浼哥缉鎬т负浠d环鐨勩€傚彧鏈夊湪鍙備笌鍒嗗竷寮忎簨鍔$殑鍚勪釜鏁版嵁搴撳疄渚嬮兘鑳藉姝e父宸ヤ綔鐨勫墠鎻愪笅锛屽垎甯冨紡浜嬪姟鎵嶈兘澶熼『鍒╁畬鎴愶紝鍙鏈変竴涓伐浣滀笉姝e父锛屾暣涓簨鍔″氨涓嶈兘瀹屾垚銆傝繖鏍凤紝绯荤粺鐨勫彲鐢ㄦ€у氨鐩稿綋浜庡弬鍔犲垎甯冨紡浜嬪姟鐨勫悇瀹炰緥鐨勫彲鐢ㄦ€т箣绉紝瀹炰緥瓒婂锛屽彲鐢ㄦ€т笅闄嶈秺鏄庢樉銆備粠鎬ц兘鍜屽彲浼哥缉鎬ц搴︾湅锛岄鍏堟槸浜嬪姟鐨勬€绘寔缁椂闂撮€氬父鏄悇瀹炰緥鎿嶄綔鏃堕棿涔嬪拰锛屽洜涓轰竴涓簨鍔′腑鐨勫悇涓搷浣滈€氬父鏄『搴忔墽琛岀殑锛岃繖鏍蜂簨鍔$殑鍝嶅簲鏃堕棿灏变細澧炲姞寰堝锛涘叾娆℃槸涓€鑸琖eb搴旂敤鐨勪簨鍔¢兘涓嶅ぇ锛屽崟鏈烘搷浣滄椂闂翠篃灏卞嚑姣鐢氳嚦涓嶅埌1姣锛屼竴浣嗘秹鍙婂埌鍒嗗竷寮忎簨鍔★紝鎻愪氦鏃惰妭鐐归棿鐨勭綉缁滈€氫俊寰€杩旇繃绋嬩篃涓烘绉掔骇鍒紝瀵逛簨鍔″搷搴旀椂闂寸殑褰卞搷涔熶笉鍙拷瑙嗐€傜敱浜庝簨鍔℃寔缁椂闂村欢闀匡紝浜嬪姟瀵圭浉鍏宠祫婧愮殑閿佸畾鏃堕棿涔熺浉搴斿鍔狅紝浠庤€屽彲鑳戒弗閲嶅鍔犱簡骞跺彂鍐茬獊锛屽奖鍝嶅埌绯荤粺鍚炲悙鐜囧拰鍙几缂╂€с€?br>
姝f槸鐢变簬鍒嗗竷寮忎簨鍔℃湁浠ヤ笂闂锛宔Bay鍦ㄨ璁′笂灏变笉閲囩敤鍒嗗竷寮忎簨鍔★紝鑰屾槸閫氳繃鍏跺畠閫斿緞鏉ヨВ鍐虫暟鎹竴鑷存€ч棶棰樸€傚叾涓娇鐢ㄧ殑鏈€閲嶈鐨勬妧鏈氨鏄秷鎭槦鍒楀拰娑堟伅搴旂敤鐘舵€佽〃銆?br>
涓句釜渚嬪瓙銆傚亣璁剧郴缁熶腑鏈変互涓嬩袱涓〃
user(id, name, amt_sold, amt_bought)
transaction(xid, seller_id, buyer_id, amount)
鍏朵腑user琛ㄨ褰曠敤鎴蜂氦鏄撴眹鎬讳俊鎭紝transaction琛ㄨ褰曟瘡涓氦鏄撶殑璇︾粏淇℃伅銆?br>
杩欐牱锛屽湪杩涜涓€绗斾氦鏄撴椂锛岃嫢浣跨敤浜嬪姟锛屽氨闇€瑕佸鏁版嵁搴撹繘琛屼互涓嬫搷浣滐細
begin;
INSERT INTO transaction VALUES(xid, $seller_id, $buyer_id, $amount);
UPDATE user SET amt_sold = amt_sold + $amount WHERE id = $seller_id;
UPDATE user SET amt_bought = amt_bought + $amount WHERE id = $buyer_id;
commit;
鍗冲湪transaction琛ㄤ腑璁板綍浜ゆ槗淇℃伅锛岀劧鍚庢洿鏂板崠瀹跺拰涔板鐨勭姸鎬併€?br>
鍋囪transaction琛ㄥ拰user琛ㄥ瓨鍌ㄥ湪涓嶅悓鐨勮妭鐐逛笂锛岄偅涔堜笂杩颁簨鍔″氨鏄竴涓垎甯冨紡浜嬪姟銆傝娑堥櫎杩欎竴鍒嗗竷寮忎簨鍔★紝灏嗗畠鎷嗗垎鎴愪袱涓瓙浜嬪姟锛屼竴涓洿鏂皌ransaction琛紝涓€涓洿鏂皍ser琛ㄦ槸涓嶈鐨勶紝鍥犱负鏈夊彲鑳絫ransaction琛ㄦ洿鏂版垚鍔熷悗锛屾洿鏂皍ser澶辫触锛岀郴缁熷皢涓嶈兘鎭㈠鍒颁竴鑷寸姸鎬併€?br>
瑙e喅鏂规鏄娇鐢ㄦ秷鎭槦鍒椼€傚涓嬫墍绀猴紝鍏堝惎鍔ㄤ竴涓簨鍔★紝鏇存柊transaction琛ㄥ悗锛屽苟涓嶇洿鎺ュ幓鏇存柊user琛紝鑰屾槸灏嗚瀵箄ser琛ㄨ繘琛岀殑鏇存柊鎻掑叆鍒版秷鎭槦鍒椾腑銆傚彟澶栨湁涓€涓紓姝ヤ换鍔¤疆璇㈤槦鍒楀唴瀹硅繘琛屽鐞嗐€?br>begin;
INSERT INTO transaction VALUES(xid, $seller_id, $buyer_id, $amount);
put_to_queue 鈥渦pdate user(鈥渟eller鈥? $seller_id, amount);
put_to_queue 鈥渦pdate user(鈥渂uyer鈥? $buyer_id, amount);
commit;
for each message in queue
begin;
dequeue message;
if message.type = 鈥渟eller鈥?then
UPDATE user SET amt_sold = amt_sold + message.amount WHERE id = message.user_id;
else
UPDATE user SET amt_bought = amt_bought + message.amount WHERE id = message.user_id;
end
commit;
end
涓婅堪瑙e喅鏂规鐪嬩技瀹岀編锛屽疄闄呬笂杩樻病鏈夎В鍐冲垎甯冨紡闂銆備负浜嗕娇绗竴涓簨鍔′笉娑夊強鍒嗗竷寮忔搷浣滐紝娑堟伅闃熷垪蹇呴』涓巘ransaction琛ㄤ娇鐢ㄥ悓涓€濂楀瓨鍌ㄨ祫婧愶紝浣嗕负浜嗕娇绗簩涓簨鍔℃槸鏈湴鐨勶紝娑堟伅闃熷垪瀛樺偍鍙堝繀椤讳笌user琛ㄥ湪涓€璧枫€傝繖涓よ€呮槸涓嶅彲鑳藉悓鏃舵弧瓒崇殑銆?br>
濡傛灉娑堟伅鍏锋湁鎿嶄綔骞傜瓑鎬э紝涔熷氨鏄竴涓秷鎭搴旂敤澶氭涓庡簲鐢ㄤ竴娆′骇鐢熺殑鏁堟灉鏄竴鏍风殑璇濓紝涓婅堪闂鏄緢濂借В鍐崇殑锛屽彧瑕佸皢娑堟伅闃熷垪鏀惧埌transaction琛ㄤ竴璧凤紝鐒跺悗鍦ㄧ浜屼釜浜嬪姟涓紝鍏堝簲鐢ㄦ秷鎭紝鍐嶄粠娑堟伅闃熷垪涓垹闄ゃ€傜敱浜庢秷鎭槦鍒楀瓨鍌ㄤ笌user琛ㄤ笉鍦ㄤ竴璧凤紝搴旂敤娑堟伅鍚庯紝鍙兘杩樻病鏉ュ緱鍙婂皢搴旂敤杩囩殑娑堟伅浠庨槦鍒椾腑鍒犻櫎鏃剁郴缁熷氨鍑烘晠闅滀簡銆傝繖鏃剁郴缁熸仮澶嶅悗浼氶噸鏂板簲鐢ㄤ竴娆¤繖涓€娑堟伅锛岀敱浜庡箓绛夋€э紝搴旂敤澶氭涔熻兘浜х敓姝g‘鐨勭粨鏋溿€?br>
浣嗗疄闄呮儏鍐典笅锛屾秷鎭緢闅惧叿鏈夊箓绛夋€э紝姣斿涓婅堪鐨刄PDATE鎿嶄綔锛屾墽琛屼竴娆″拰鎵ц澶氭鐨勭粨鏉熸樉鐒舵槸涓嶄竴鏍风殑銆傝В鍐宠繖涓€闂鐨勬柟娉曟槸浣跨敤鍙︿竴涓〃璁板綍宸茬粡琚垚鍔熷簲鐢ㄧ殑娑堟伅锛屽苟涓旇繖涓〃浣跨敤涓巙ser琛ㄧ浉鍚岀殑瀛樺偍銆傚亣璁惧鍔犱互涓嬭〃 message_applied(msg_id)璁板綍琚垚鍔熷簲鐢ㄧ殑娑堟伅锛屽垯浜х敓鏈€缁堢殑瑙e喅鏂规濡備笅锛?br>begin;
INSERT INTO transaction VALUES(xid, $seller_id, $buyer_id, $amount);
put_to_queue 鈥渦pdate user(鈥渟eller鈥? $seller_id, amount);
put_to_queue 鈥渦pdate user(鈥渂uyer鈥? $buyer_id, amount);
commit;
for each message in queue
begin;
SELECT count(*) as cnt FROM message_applied WHERE msg_id = message.id;
if cnt = 0 then
if message.type = 鈥渟eller鈥?then
UPDATE user SET amt_sold = amt_sold + message.amount WHERE id = message.user_id;
else
UPDATE user SET amt_bought = amt_bought + message.amount WHERE id = message.user_id;
end
INSERT INTO message_applied VALUES(message.id);
end
commit;
if 涓婅堪浜嬪姟鎴愬姛
dequeue message
DELETE FROM message_applied WHERE msg_id = message.id;
end
end
鎴戜滑鏉