钱包余额增加悲观锁

This commit is contained in:
cano
2024-03-29 11:10:00 +08:00
parent 4b47fe7250
commit 81a95f47a0
3 changed files with 63 additions and 2 deletions

View File

@ -118,6 +118,8 @@ class CustomerWalletBalanceTransactionModel extends ApiBaseModel
$oCustomerWalletBalanceModel = new CustomerWalletBalanceModel();
$resWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($bean->getUid(), $bean->getCurrencyCode());
if (!$resWalletBalanceModel) throw new ModelException('wallet not found');
//加悲观锁
$resWalletBalanceModel = $oCustomerWalletBalanceModel->findByWhereWithLock($resWalletBalanceModel->id);
$bean->setWalletId($resWalletBalanceModel->id);
$bean->setBeforeTotalAmount($resWalletBalanceModel->total_amount);
$bean->setAfterTotalAmount(Math::bcAdd($resWalletBalanceModel->total_amount, $bean->getAmount()));
@ -153,6 +155,8 @@ class CustomerWalletBalanceTransactionModel extends ApiBaseModel
$oCustomerWalletBalanceModel = new CustomerWalletBalanceModel();
$resWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($bean->getUid(), $bean->getCurrencyCode());
if (!$resWalletBalanceModel) throw new ModelException('wallet not found');
//加悲观锁
$resWalletBalanceModel = $oCustomerWalletBalanceModel->findByWhereWithLock($resWalletBalanceModel->id);
if (Math::bcComp($resWalletBalanceModel->available_amount, abs($bean->getAmount())) != -1) throw new ModelException('balance not enough');
$bean->setWalletId($resWalletBalanceModel->id);
$bean->setBeforeTotalAmount($resWalletBalanceModel->total_amount);
@ -189,6 +193,8 @@ class CustomerWalletBalanceTransactionModel extends ApiBaseModel
$item = $this->findItem($itemId->id);
$resWalletBalanceModel = $oCustomerWalletBalanceModel->findItem($item->wallet_id);
if (!$resWalletBalanceModel) throw new ModelException('wallet not found');
//加悲观锁
$resWalletBalanceModel = $oCustomerWalletBalanceModel->findByWhereWithLock($resWalletBalanceModel->id);
$updateItem = [
'id' => $item->id,
'status' => self::STATUS_SUCCESS,
@ -236,9 +242,13 @@ class CustomerWalletBalanceTransactionModel extends ApiBaseModel
$oCustomerWalletBalanceModel = new CustomerWalletBalanceModel();
$resSenderWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($senderWalletTransactionBean->getUid(), $senderWalletTransactionBean->getCurrencyCode());
if (!$resSenderWalletBalanceModel) throw new ModelException('sender wallet not found');
//加悲观锁
$resSenderWalletBalanceModel = $oCustomerWalletBalanceModel->findByWhereWithLock($resSenderWalletBalanceModel->id);
//查询接收人余额
$resReceiverWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($receiverWalletTransactionBean->getUid(), $receiverWalletTransactionBean->getCurrencyCode());
if (!$resReceiverWalletBalanceModel) throw new ModelException('receiver wallet not found');
//加悲观锁
$resReceiverWalletBalanceModel = $oCustomerWalletBalanceModel->findByWhereWithLock($resReceiverWalletBalanceModel->id);
//检查发送人余额是否足够
if (Math::bcComp($resSenderWalletBalanceModel->available_amount, abs($senderWalletTransactionBean->getAmount())) != -1) throw new ModelException('balance not enough');
@ -291,6 +301,8 @@ class CustomerWalletBalanceTransactionModel extends ApiBaseModel
$oCustomerWalletBalanceModel = new CustomerWalletBalanceModel();
$resWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($bean->getUid(), $bean->getCurrencyCode());
if (!$resWalletBalanceModel) throw new ModelException('wallet not found');
//加悲观锁
$resWalletBalanceModel = $oCustomerWalletBalanceModel->findByWhereWithLock($resWalletBalanceModel->id);
if (Math::bcComp($resWalletBalanceModel->available_amount, abs($bean->getAmount())) != -1) throw new ModelException('balance not enough');
$bean->setWalletId($resWalletBalanceModel->id);
$bean->setBeforeTotalAmount($resWalletBalanceModel->total_amount);
@ -328,6 +340,8 @@ class CustomerWalletBalanceTransactionModel extends ApiBaseModel
$oCustomerWalletBalanceModel = new CustomerWalletBalanceModel();
$resWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($bean->getUid(), $bean->getCurrencyCode());
if (!$resWalletBalanceModel) throw new ModelException('wallet not found');
//加悲观锁
$resWalletBalanceModel = $oCustomerWalletBalanceModel->findByWhereWithLock($resWalletBalanceModel->id);
$bean->setWalletId($resWalletBalanceModel->id);
$bean->setBeforeTotalAmount($resWalletBalanceModel->total_amount);
$bean->setAfterTotalAmount(Math::bcAdd($resWalletBalanceModel->total_amount, $bean->getAmount()));
@ -363,6 +377,8 @@ class CustomerWalletBalanceTransactionModel extends ApiBaseModel
$oCustomerWalletBalanceModel = new CustomerWalletBalanceModel();
$resWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($bean->getUid(), $bean->getCurrencyCode());
if (!$resWalletBalanceModel) throw new ModelException('wallet not found');
//加悲观锁
$resWalletBalanceModel = $oCustomerWalletBalanceModel->findByWhereWithLock($resWalletBalanceModel->id);
$bean->setWalletId($resWalletBalanceModel->id);
$bean->setBeforeTotalAmount($resWalletBalanceModel->total_amount);
$bean->setAfterTotalAmount(Math::bcAdd($resWalletBalanceModel->total_amount, $bean->getAmount()));
@ -398,6 +414,8 @@ class CustomerWalletBalanceTransactionModel extends ApiBaseModel
$oCustomerWalletBalanceModel = new CustomerWalletBalanceModel();
$resWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($bean->getUid(), $bean->getCurrencyCode());
if (!$resWalletBalanceModel) throw new ModelException('wallet not found');
//加悲观锁
$resWalletBalanceModel = $oCustomerWalletBalanceModel->findByWhereWithLock($resWalletBalanceModel->id);
$bean->setWalletId($resWalletBalanceModel->id);
$bean->setBeforeTotalAmount($resWalletBalanceModel->total_amount);
$bean->setAfterTotalAmount(Math::bcAdd($resWalletBalanceModel->total_amount, $bean->getAmount()));
@ -444,6 +462,8 @@ class CustomerWalletBalanceTransactionModel extends ApiBaseModel
$oCustomerWalletBalanceModel = new CustomerWalletBalanceModel();
$resWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($bean->getUid(), $bean->getCurrencyCode());
if (!$resWalletBalanceModel) throw new ModelException('wallet not found');
//加悲观锁
$resWalletBalanceModel = $oCustomerWalletBalanceModel->findByWhereWithLock($resWalletBalanceModel->id);
$bean->setWalletId($resWalletBalanceModel->id);
$bean->setBeforeTotalAmount($resWalletBalanceModel->total_amount);
$bean->setAfterTotalAmount(Math::bcAdd($resWalletBalanceModel->total_amount, $bean->getAmount()));
@ -491,6 +511,8 @@ class CustomerWalletBalanceTransactionModel extends ApiBaseModel
$oCustomerWalletBalanceModel = new CustomerWalletBalanceModel();
$resWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($bean->getUid(), $bean->getCurrencyCode());
if (!$resWalletBalanceModel) throw new ModelException('wallet not found');
//加悲观锁
$resWalletBalanceModel = $oCustomerWalletBalanceModel->findByWhereWithLock($resWalletBalanceModel->id);
$bean->setWalletId($resWalletBalanceModel->id);
$bean->setBeforeTotalAmount($resWalletBalanceModel->total_amount);
$bean->setAfterTotalAmount(Math::bcAdd($resWalletBalanceModel->total_amount, $bean->getAmount()));
@ -528,6 +550,8 @@ class CustomerWalletBalanceTransactionModel extends ApiBaseModel
$oCustomerWalletBalanceModel = new CustomerWalletBalanceModel();
$resWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($bean->getUid(), $bean->getCurrencyCode());
if (!$resWalletBalanceModel) throw new ModelException('wallet not found');
//加悲观锁
$resWalletBalanceModel = $oCustomerWalletBalanceModel->findByWhereWithLock($resWalletBalanceModel->id);
$bean->setWalletId($resWalletBalanceModel->id);
$bean->setBeforeTotalAmount($resWalletBalanceModel->total_amount);
$bean->setAfterTotalAmount(Math::bcAdd($resWalletBalanceModel->total_amount, $bean->getAmount()));
@ -571,6 +595,8 @@ class CustomerWalletBalanceTransactionModel extends ApiBaseModel
$oCustomerWalletBalanceModel = new CustomerWalletBalanceModel();
$resWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($bean->getUid(), $bean->getCurrencyCode());
if (!$resWalletBalanceModel) throw new ModelException('wallet not found');
//加悲观锁
$resWalletBalanceModel = $oCustomerWalletBalanceModel->findByWhereWithLock($resWalletBalanceModel->id);
$bean->setWalletId($resWalletBalanceModel->id);
$bean->setBeforeTotalAmount($resWalletBalanceModel->total_amount);
$bean->setAfterTotalAmount(Math::bcAdd($resWalletBalanceModel->total_amount, $bean->getAmount()));
@ -631,6 +657,9 @@ class CustomerWalletBalanceTransactionModel extends ApiBaseModel
//查询买家余额
$oCustomerWalletBalanceModel = new CustomerWalletBalanceModel();
$resBuyerWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($buyerWalletTransactionBean->getUid(), $buyerWalletTransactionBean->getCurrencyCode());
if (!$resBuyerWalletBalanceModel) throw new ModelException('buyer wallet not found');
//加悲观锁
$resBuyerWalletBalanceModel = $oCustomerWalletBalanceModel->findByWhereWithLock($resBuyerWalletBalanceModel->id);
//检查买家余额是否足够
if (Math::bcComp($resBuyerWalletBalanceModel->available_amount, abs($orderBean->getAmount())) == -1) throw new ModelException('buyer balance not enough');
@ -641,6 +670,8 @@ class CustomerWalletBalanceTransactionModel extends ApiBaseModel
//设置卖家卖家钱包id
$resSellerWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($sellerWalletTransactionBean->getUid(), $sellerWalletTransactionBean->getCurrencyCode());
if (!$resSellerWalletBalanceModel) throw new ModelException('seller wallet not found');
//加悲观锁
$resSellerWalletBalanceModel = $oCustomerWalletBalanceModel->findByWhereWithLock($resSellerWalletBalanceModel->id);
$sellerWalletTransactionBean->setWalletId($resSellerWalletBalanceModel->id);
$sellerWalletTransactionBean->setBeforeTotalAmount($resSellerWalletBalanceModel->total_amount);
$sellerWalletTransactionBean->setAfterTotalAmount(Math::bcAdd($resSellerWalletBalanceModel->total_amount, $sellerWalletTransactionBean->getAmount()));
@ -703,6 +734,8 @@ class CustomerWalletBalanceTransactionModel extends ApiBaseModel
$oCustomerWalletBalanceModel = new CustomerWalletBalanceModel();
$resWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($bean->getUid(), $bean->getCurrencyCode());
if (!$resWalletBalanceModel) throw new ModelException('wallet not found');
//加悲观锁
$resWalletBalanceModel = $oCustomerWalletBalanceModel->findByWhereWithLock($resWalletBalanceModel->id);
//检查余额是否足够
if (Math::bcComp(Math::bcSub($resWalletBalanceModel->available_amount, $withdraw_fee), abs($bean->getAmount())) == -1) throw new ModelException('balance not enough');
@ -744,6 +777,8 @@ class CustomerWalletBalanceTransactionModel extends ApiBaseModel
$oCustomerWalletBalanceModel = new CustomerWalletBalanceModel();
$resWalletBalanceModel = $oCustomerWalletBalanceModel->findItem($resModel->wallet_id);
if (!$resWalletBalanceModel) throw new ModelException('wallet not found');
//加悲观锁
$resWalletBalanceModel = $oCustomerWalletBalanceModel->findByWhereWithLock($resWalletBalanceModel->id);
if ($status == self::STATUS_SUCCESS) {
//扣减冻结金额
@ -803,6 +838,8 @@ class CustomerWalletBalanceTransactionModel extends ApiBaseModel
$oCustomerWalletBalanceModel = new CustomerWalletBalanceModel();
$resWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($bean->getUid(), $bean->getCurrencyCode());
if (!$resWalletBalanceModel) throw new ModelException('wallet not found');
//加悲观锁
$resWalletBalanceModel = $oCustomerWalletBalanceModel->findByWhereWithLock($resWalletBalanceModel->id);
$bean->setWalletId($resWalletBalanceModel->id);
$bean->setBeforeTotalAmount($resWalletBalanceModel->total_amount);
$bean->setAfterTotalAmount(Math::bcAdd($resWalletBalanceModel->total_amount, $bean->getAmount()));

View File

@ -71,7 +71,7 @@ class BaseModel extends Model
return $this->newQuery()->where($aWhere)->get($col);
}
function setLockByPrimaryKey($id,$lock_type = self::LOCK_TYPE_FOR_UPDATE): Model|\Illuminate\Database\Eloquent\Builder|null
function findByPrimaryKeyWithLock($id,$lock_type = self::LOCK_TYPE_FOR_UPDATE): Model|\Illuminate\Database\Eloquent\Builder|null
{
$model = $this->newQuery()->where($this->primaryKey, $id);
if($lock_type == self::LOCK_TYPE_FOR_SHARE){
@ -82,6 +82,17 @@ class BaseModel extends Model
return $model->first();
}
function findByWhereWithLock($id,$col=['*'],$lock_type = self::LOCK_TYPE_FOR_UPDATE): Model|\Illuminate\Database\Eloquent\Builder|null
{
$model = $this->newQuery()->where($this->primaryKey, $id);
if($lock_type == self::LOCK_TYPE_FOR_SHARE){
$model = $model->sharedLock();
}elseif ($lock_type == self::LOCK_TYPE_FOR_UPDATE){
$model = $model->lockForUpdate();
}
return $model->first($col);
}
}

View File

@ -106,6 +106,8 @@ class WalletPlatformBalanceTransactionModel extends WalletBaseModel
$oWalletPlatformBalanceModel = new WalletPlatformBalanceModel();
$resBalanceModel = $oWalletPlatformBalanceModel->findPlatformBalanceOrCreate($platform_id, $currency_code);
if (!$resBalanceModel) throw new ModelException('findPlatformBalanceOrCreate error');
//加悲观锁
$resBalanceModel = $oWalletPlatformBalanceModel->findByWhereWithLock($resBalanceModel->id);
$bean->setBalanceId($resBalanceModel->id);
$bean->setBeforeTotalAmount($resBalanceModel->total_amount);
@ -144,7 +146,8 @@ class WalletPlatformBalanceTransactionModel extends WalletBaseModel
$oWalletPlatformBalanceModel = new WalletPlatformBalanceModel();
$resBalanceModel = $oWalletPlatformBalanceModel->findPlatformBalanceOrCreate($platform_id, $currency_code);
if (!$resBalanceModel) throw new ModelException('findPlatformBalanceOrCreate error');
//加悲观锁
$resBalanceModel = $oWalletPlatformBalanceModel->findByWhereWithLock($resBalanceModel->id);
$bean->setBalanceId($resBalanceModel->id);
$bean->setBeforeTotalAmount($resBalanceModel->total_amount);
$bean->setAfterTotalAmount(Math::bcAdd($resBalanceModel->total_amount, $bean->getAmount()));
@ -182,6 +185,8 @@ class WalletPlatformBalanceTransactionModel extends WalletBaseModel
$oWalletPlatformBalanceModel = new WalletPlatformBalanceModel();
$resBalanceModel = $oWalletPlatformBalanceModel->findPlatformBalanceOrCreate($platform_id, $currency_code);
if (!$resBalanceModel) throw new ModelException('findPlatformBalanceOrCreate error');
//加悲观锁
$resBalanceModel = $oWalletPlatformBalanceModel->findByWhereWithLock($resBalanceModel->id);
$bean->setBalanceId($resBalanceModel->id);
$bean->setBeforeTotalAmount($resBalanceModel->total_amount);
@ -220,6 +225,8 @@ class WalletPlatformBalanceTransactionModel extends WalletBaseModel
$oWalletPlatformBalanceModel = new WalletPlatformBalanceModel();
$resBalanceModel = $oWalletPlatformBalanceModel->findPlatformBalanceOrCreate($platform_id, $currency_code);
if (!$resBalanceModel) throw new ModelException('findPlatformBalanceOrCreate error');
//加悲观锁
$resBalanceModel = $oWalletPlatformBalanceModel->findByWhereWithLock($resBalanceModel->id);
$bean->setBalanceId($resBalanceModel->id);
$bean->setBeforeTotalAmount($resBalanceModel->total_amount);
@ -275,6 +282,8 @@ class WalletPlatformBalanceTransactionModel extends WalletBaseModel
$oWalletPlatformBalanceModel = new WalletPlatformBalanceModel();
$resBalanceModel = $oWalletPlatformBalanceModel->findPlatformBalanceOrCreate($platform_id, $currency_code);
if (!$resBalanceModel) throw new ModelException('findPlatformBalanceOrCreate error');
//加悲观锁
$resBalanceModel = $oWalletPlatformBalanceModel->findByWhereWithLock($resBalanceModel->id);
$bean->setBalanceId($resBalanceModel->id);
$bean->setBeforeTotalAmount($resBalanceModel->total_amount);
$bean->setAfterTotalAmount(Math::bcAdd($resBalanceModel->total_amount, $bean->getAmount()));
@ -315,6 +324,8 @@ class WalletPlatformBalanceTransactionModel extends WalletBaseModel
$oWalletPlatformBalanceModel = new WalletPlatformBalanceModel();
$resBalanceModel = $oWalletPlatformBalanceModel->findPlatformBalanceOrCreate($platform_id, $currency_code);
if (!$resBalanceModel) throw new ModelException('findPlatformBalanceOrCreate error');
//加悲观锁
$resBalanceModel = $oWalletPlatformBalanceModel->findByWhereWithLock($resBalanceModel->id);
//检查余额是否足够
if (Math::bcComp(Math::bcSub($resBalanceModel->available_amount, $withdraw_fee), abs($bean->getAmount())) == -1) throw new ModelException('available_amount not enough');
$bean->setBalanceId($resBalanceModel->id);
@ -372,6 +383,8 @@ class WalletPlatformBalanceTransactionModel extends WalletBaseModel
$oWalletPlatformBalanceModel = new WalletPlatformBalanceModel();
$resBalanceModel = $oWalletPlatformBalanceModel->findItem($resModel->balance_id);
if (!$resBalanceModel) throw new ModelException('WalletPlatformBalanceModel findItem error');
//加悲观锁
$resBalanceModel = $oWalletPlatformBalanceModel->findByWhereWithLock($resBalanceModel->id);
if ($status == self::STATUS_SUCCESS) {
//变更余额