diff --git a/app/Models/Api/Wallet/CustomerWalletBalanceTransactionModel.php b/app/Models/Api/Wallet/CustomerWalletBalanceTransactionModel.php index 1fc47c6..b58c52a 100644 --- a/app/Models/Api/Wallet/CustomerWalletBalanceTransactionModel.php +++ b/app/Models/Api/Wallet/CustomerWalletBalanceTransactionModel.php @@ -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())); diff --git a/app/Models/Base/BaseModel.php b/app/Models/Base/BaseModel.php index 56ce7ef..b571c30 100644 --- a/app/Models/Base/BaseModel.php +++ b/app/Models/Base/BaseModel.php @@ -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); + } + } diff --git a/app/Models/Wallet/Platform/WalletPlatformBalanceTransactionModel.php b/app/Models/Wallet/Platform/WalletPlatformBalanceTransactionModel.php index 3ddd0d1..b9e147a 100644 --- a/app/Models/Wallet/Platform/WalletPlatformBalanceTransactionModel.php +++ b/app/Models/Wallet/Platform/WalletPlatformBalanceTransactionModel.php @@ -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) { //变更余额