我在项目中使用yii2队列。 我发送表单,然后将数据发送到队列作业中进行操作;
我希望通过重复数据(两次单击多次以同时发送表单)或从两个设备在同一时间多次发送表单时,发送到队列的第一个请求成功事务并保存当前记录状态字段锁定状态,并且在所有其他请求中都有失败的事务,因为记录被锁定,并且不应使用超过1次。
但是队列无法正常工作,并通过重复数据保存2,3个成功事务,并在第一个队列作业使用了1次以上后进行记录。 如何配置队列以在每秒内运行1个作业
public function actionCard()
{
$card = new CardTransaction();
if( $card->load(Yii::$app->request->post()) ){
$cardTransaction = CardTransactions::find()
->select(["*","RIGHT(card,4) AS card_number"])
->where([
'RIGHT(card,4)' => $card->cardNumber,
'transfer_amount' => $card->amount,
'status' => CardTransactions::STATUS['UNUSED']
])
->one();
if( $cardTransaction == null )
{
return $this->redirect(['card']);
}
// Send Request To Queue
$sendToQueue = Yii::$app->queue->push(new SubmitCard([
'userId' => Yii::$app->user->id,
'cardNumber' => $card->cardNumber,
'amount' => $card->amount,
'code' => $card->code
]));
if( $sendToQueue ){
return $this->redirect(['card']);
}else{
return $this->redirect(['card']);
}
}
return $this->render('card',[
'model' => $card,
]);
}
和我的工作类别
class SubmitCard extends BaseObject implements JobInterface {
public $userId;
public $cardNumber;
public $amount;
public $code;
public function execute( $queue ) {
$user = User::findOne($this->userId);
$transaction = Yii::$app->db->beginTransaction();
try {
/** @var $cardTransaction CardTransactions*/
$cardTransaction = CardTransactions::find()
->select(["*","RIGHT(card,4) AS card_number"])
->where([
'RIGHT(card,4)' => $this->cardNumber,
'transfer_amount' => $this->amount,
'status' => CardTransactions::STATUS['UNUSED']
])
->one();
if( $cardTransaction == null )
{
throw new Exception('Your Request Data is invalid');
}
$cardTransaction->status = CardTransactions::STATUS['SUCCESS'];
$cardTransaction->user_id = $user->id;
$user->deposit += (int)$cardTransaction->transfer_amount;
$user->balance += (int)$cardTransaction->transfer_amount;
if( !$cardTransaction->save() || !$user->save() ){
throw new Exception('Error in save data');
}
General::successTransaction($user->id,Transaction::TYPE['INCREASE_CARD'],$this->amount,Transaction::LOGIN_FROM['SITE'],$user->balance);
$transaction->commit();
} catch(\Exception $e) {
$transaction->rollBack();
// Save Fail Transaction
General::failTransaction($user->id,Transaction::TYPE['INCREASE_CARD'],$this->amount,Transaction::LOGIN_FROM['SITE'],$user->balance);
throw $e;
} catch(\Throwable $e) {
$transaction->rollBack();
General::failTransaction($user->id,Transaction::TYPE['INCREASE_CARD'],$this->amount,Transaction::LOGIN_FROM['SITE'],$user->balance);
throw $e;
}
}
}