1. 程式人生 > >電商中使用者餘額/積分以及庫存的設計

電商中使用者餘額/積分以及庫存的設計

在電商中,我們總會遇到使用者餘額/積分和庫存的問題,總是怕會出現使用者餘額/積分用超或商品超賣的情況。這次就來了解一下怎麼設計使用者餘額/積分,怎麼來處理庫存問題。

一、使用者餘額/積分設計

1、概述

對於使用者餘額/積分,一方面我們需要知道使用者的總積分有多少(這部分是可用積分),另一方面我還還需要知道使用者的積分變動記錄(積分的增加和減少)。

同時,在電商中,關於積分的操作不僅僅都是同步的,也就是我們可以直接增加或扣減積分,為了提升服務的效能,如果積分的操作存在非同步的情況,那麼我們就不能直接進行增加或扣減積分了,這種情況下,我們可以引入積分凍結的概念,暫緩對積分的處理。

另外,如果使用者的積分變動較為集中,即存在單位時間內增加和扣減同時出現的情況,那麼我們還需要引入分散式鎖對使用者積分進行保護,避免多個執行緒同時操作使用者積分,造成積分異常。

2、積分表的設計

使用者積分表的設計,我們重點需要關注一下三個欄位:

欄位1 欄位2 欄位3
使用者標識 總積分 可用積分

我們需要注意一下總積分可用積分的區別,一般情況下總積分和可用積分總是相同的,但當需要積分凍結時,我們操作凍結的是使用者的可用積分,此時使用者的總積分和可用積分就是不相同的。我們也可以通過兩者是否相同來判斷是否存在凍結中的積分

3、積分明細表的設計

欄位 說明
使用者標識 唯一標識一個使用者
操作積分 本次操作的積分值
可用積分 本次操作可以使用的積分值(用於扣減)
操作型別 增加積分、減少積分
積分型別 業務型別:消費送、支付扣減、過期等
積分狀態 有效、已扣除、已過期、凍結中、凍結返還、凍結釦減
積分來源 當扣減積分時,儲存扣減的積分記錄id,用於追溯積分

4、增加積分

增加積分,只需要增加使用者積分、生成積分記錄即可
使用者積分表:

使用者標識 總積分 可用積分
張三 100 100

積分記錄表:

記錄id 使用者標識 操作積分 可用積分 操作型別 積分型別 積分狀態 積分來源
1 張三 100 100 增加 消費送 有效

5、直接扣減積分

如果使用者支付使用了20積分,那麼使用者積分情況如下:
使用者積分表:

使用者標識 總積分 可用積分
張三 80 80

積分記錄表:

記錄id 使用者標識 操作積分 可用積分 操作型別 積分型別 積分狀態 積分來源
1 張三 100 80 增加 消費送 有效
2 張三 20 0 減少 支付用 有效 1

扣減時,我們要從積分記錄中找到可扣除的積分(增加型別的積分且可用積分為0)進行扣除。
如果此時使用者再使用了80積分,那麼使用者的積分情況是這樣的:

使用者積分表:

使用者標識 總積分 可用積分
張三 0 0

積分記錄表:

記錄id 使用者標識 操作積分 可用積分 操作型別 積分型別 積分狀態 積分來源
1 張三 100 0 增加 消費送 已扣除
2 張三 20 0 減少 支付用 有效 1
3 張三 80 0 減少 支付用 有效 1

6、凍結使用者積分

引入凍結的目的是為了在使用者使用積分的時候,不會真的扣除使用者的積分,而是先凍結起來,當確定扣除的操作成功後,再真正的扣除積分,如果操作失敗了,則要解凍積分。同時還需要用定時去處理哪些需要解凍而沒有正常解凍的積分。

假設使用者初始有100的可用積分,當支付需要使用20積分時,先扣除可用積分,生成凍結積分記錄,使用者的積分情況是這樣的:
使用者積分表:

使用者標識 總積分 可用積分
張三 100 80

積分記錄表:

記錄id 使用者標識 操作積分 可用積分 操作型別 積分型別 積分狀態 積分來源
1 張三 20 0 減少 支付用 凍結中

如果非同步訊息確認使用者支付成功,那麼就解除積分的凍結狀態,此時的使用者積分情況如下:
使用者積分表:

使用者標識 總積分 可用積分
張三 80 80

積分記錄表:

記錄id 使用者標識 操作積分 可用積分 操作型別 積分型別 積分狀態 積分來源
1 張三 20 0 減少 支付用 凍結完成,扣減 扣減的記錄id

7、解凍使用者積分

當出現使用者使用積分失敗的情況時,我們需要去把凍結中的積分進行解凍,避免影響使用者權益。在解凍時,一定要確認確實時使用者使用積分失敗了,需要解凍,不要出現解凍錯誤的情況。一般情況下,我們會使用定時任務來解凍積分。解凍時,使用者積分情況如下:
使用者積分表:

使用者標識 總積分 可用積分
張三 100 100

積分記錄表:

記錄id 使用者標識 操作積分 可用積分 操作型別 積分型別 積分狀態 積分來源
1 張三 20 0 減少 支付用 凍結失敗,扣減
2 張三 20 0 增加 凍結退還 凍結失敗,退還

二、庫存處理設計

在處理庫存時,為了避免賣超,在扣減庫存時,一般都會先去判斷庫存是否足夠,如果足夠,才會去扣減庫存。分散式系統一定要考慮併發的問題,如果查詢時庫存是足夠的,扣減的時候卻不足了,如何處理呢?一般我們會考慮加上鎖,保證當一個執行緒操作庫存時,其他執行緒進行等待。但是,鎖的出現,必定會影響效率。那麼如何設計才能既保證了庫存的安全又提高效率呢?解決辦法就是通過sql來解決。
比如,我們用t_goods標識庫存表,inventory欄位標識庫存,需要減少N個庫存時,通過如下sql來執行:

update t_goods set inventory = inventory - #{N} where inventory >= #{N}

我們通過在update語句新增where條件,來確保扣減庫存時,庫存一定不小於扣減的數量。

以上就是關於使用者餘額/積分和庫存處理的設計,希望能對大家有所幫助!