摘要:預算管理要求消耗的物品的數量能夠按照預算庫存進行消耗,不能超額,盡可能的保障預算的消耗率。描述了用戶執行搶購的交易信息訂單號,搶購標的編號,狀態凍結失敗成功交易數量,用戶編號。
題目
背景描述:
在現今電子商務場景下,預算管理在很多場景下都有廣泛應用,比如營銷獎品,積分、紅包的發放、商品庫存管理等。預算管理要求消耗的物品的數量能夠按照預算庫存進行消耗,不能超額,盡可能的保障預算的消耗率。
大規模請求量以及分布式環境下,預算管理問題更加突出,如果預算控制不合理,則會出現物品超發或是預算消耗率不高的情況,超發會導致直接的資金損失出現;預算消耗率不高則會導致商品無法賣出、獎品無法發放等問題,從而導致間接的資金損失。
根據上面的背景,用偽代碼描述如下功能,在分布式集群環境下,有一批積分需要發放給用戶,存放在數據庫中,實現預算的扣減方法。
//: TODO 可自行定義變量 /** * 扣減預算 * @param consumption 當前需要扣減的消耗量 * @return 預算的扣減是否成功 */ public boolean budgetDeduct(int consumption){ //: TODO 完成此處的代碼 }思考
作為新手,可能只會想到加鎖,比如先加上悲觀鎖(先來個select for update,鎖住之后再來個update 加上超發的where限制等)。所有的事情都在一個服務方法中完成,即可。好處是實現簡單,壞處呢,比如響應慢,執行效率低(悲觀鎖)等。
如果是老手,實現就會比較復雜
標的物表 target_tbl(id,name,total_number,available_number,froze_number)
搶購交易表trade_order_tbl(order_id,target_tbl_id,state,trade_number,user_id)
target_tbl描述了搶購的目標物件信息:名字,總數量,可用數量,凍結數量。
trade_order_tbl描述了用戶執行搶購的交易信息:訂單號,搶購標的編號,狀態(凍結/失敗/成功),交易數量,用戶編號。
public boolean budgetDeduct(int consumption){ Long tradeOrderId=frozeTarget(userId,targetId,consumption); if(tradeOrderId !=null){ //凍結成功之后,執行業務操作,或是檢查 bool isBusiSucc = doBusiness(); //業務操作成功,則更新交易,并將搶購商品入個人賬 if(isBusiSucc){ return updateTrade() }else{ //業務操作失敗,則解凍交易 return undoFrozeTarget(); } }else{ //凍結不成功,返回失敗 return false; } } /** * 需要事務支持,異常回滾 * @param userId 搶購用戶編號 * @param targetId 搶購商品編號 * @param consumption 搶購數量 * @return **/ private Long frozeTarget(String userId,String targetId, int consumption){ int updated=0; //通過樂觀鎖的方式進行更新,嘗試5次,5次仍舊失敗,則認為凍結失敗 for(int i=0;i<5;i++){ //update target_tbl //set froze_number = froze_number+consumption ,available_number = available_number-consumptionwhere available_number>=consumption updated = executeFroze(); if(updated != 0) { break; }else{ continue; } } if(update == 0){//凍結不成功 return null; }else{ //凍結成功,添加搶購交易記錄 Long tradeOrderId = createOrder(); return tradeOrderId; } } /** *需要事務支持,異常回滾 *失敗需要重試 */ private bool updateTrade(){ //1.更新交易表狀態為成功 //2.更新標的表,使標的表的total_number,available_number,froze_number 減去交易表的trade_number //3.更新用戶信息 } /** *需要事務支持,異常回滾 *失敗需要重試 */ private bool undoFrozeTarget(){ //1.更新交易表狀態為失敗 //2.更新標的表,使標的表的available_number+trade_number,froze_number-trade_number }另一個思路
一般我們在設計的時候,流水表和商戶賬戶表是同時更新的,比如用戶充值,沖完之后,用戶賬戶就是更新后的值。但是在一些業務場景下,流水表和賬戶表不需要同時更新,賬戶表通過定時任務來批量更新,或是業務上允許賬戶變動能容忍一定的滯后。這帶了的思考是,先將完整業務流程細分到更新表的操作,再從業務上去梳理,將幾個表的操作組合起來,重新組合為業務場景。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/70432.html
摘要:接下來,我主要從三個階段回顧我的秋招,分別是前期中期尾聲。到了這里,我的秋招算是正式的塵埃落定了,簽完三方后,我的秋招結束了。四復盤總結這次的復盤主要是我自己整個秋招的歷程縮影,很多細節無法在一篇文章就說清楚。 ...
摘要:最近要招一名中高級程序員有位同學的面試表現我們幾位面試官都覺得不錯思維很活躍知識面也還挺廣尤其是主動提及最近還在研究這個高性能框架并說出了基本實現原理表現出喜歡鉆研技術的態度唯一的缺點就是邏輯思維不太縝密工作經驗只有年多但我們都覺得稍加培養 最近要招一名中高級程序員, 有位同學的面試表現我們幾位面試官都覺得不錯: 思維很活躍, 知識面也還挺廣, 尤其是主動提及最近還在研究Disrupt...
摘要:正如我標題所說,簡歷被拒。看了我簡歷之后說頭條競爭激烈,我背景不夠,點到為止。。三準備面試其實從三月份投遞簡歷開始準備面試到四月份收,也不過個月的時間,但這都是建立在我過去一年的積累啊。 本文是 無精瘋 同學投稿的面試經歷 關注微信公眾號:進擊的java程序員K,即可獲取最新BAT面試資料一份 在此感謝 無精瘋 同學的分享 目錄: 印象中的頭條 面試背景 準備面試 ...
摘要:正如我標題所說,簡歷被拒。看了我簡歷之后說頭條競爭激烈,我背景不夠,點到為止。。三準備面試其實從三月份投遞簡歷開始準備面試到四月份收,也不過個月的時間,但這都是建立在我過去一年的積累啊。 本文是 無精瘋 同學投稿的面試經歷 關注微信公眾號:進擊的java程序員K,即可獲取最新BAT面試資料一份 在此感謝 無精瘋 同學的分享目錄:印象中的頭條面試背景準備面試頭條一面(Java+項目)頭條...
閱讀 2306·2021-11-23 10:09
閱讀 2885·2021-10-12 10:11
閱讀 2594·2021-09-29 09:35
閱讀 1337·2019-08-30 15:53
閱讀 2261·2019-08-30 11:15
閱讀 2904·2019-08-29 13:01
閱讀 2290·2019-08-28 18:15
閱讀 3363·2019-08-26 12:13