Le contenu de cet article concerne le développement de Yii2 : Comment encapsuler les transactions de manière similaire à une fermeture. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.
Lors de l'exécution d'une transaction dans le contrôleur, le code général est le suivant :
$transaction = Yii::$app->db->beginTransaction(); try { //一些业务代码 $transaction->commit(); } catch (\Exception $e) { $transaction->rollBack(); throw $e; }
Je pensais donc, cette structure de code, seulement // certains codes métiers sont différents, mais il doit être répété plusieurs fois. N'est-ce pas redondant ? Et non ! bien! regarder! , j'ai donc essayé de trouver une solution. Au début, j'ai trouvé une question similaire sur stackflow. Il existe une solution pour l'encapsuler dans le modèle, mais cela pose certains problèmes, comme les transactions imbriquées. pouvez cliquer ici pour voir la question.
Notre framework Yii fournit une méthode transaction. À première vue, il semble qu'il ne puisse pas résoudre le problème du passage des paramètres. Ignorons-le pour l'instant, la méthode est appelée comme suit :
Yii::$app->db->transaction(function() { //一些业务代码 });
Regardons le code source de cette méthode
/** * Executes callback provided in a transaction. * * @param callable $callback a valid PHP callback that performs the job. Accepts connection instance as parameter. * @param string|null $isolationLevel The isolation level to use for this transaction. * See [[Transaction::begin()]] for details. * @throws \Exception|\Throwable if there is any exception during query. In this case the transaction will be rolled back. * @return mixed result of callback function */ public function transaction(callable $callback, $isolationLevel = null) { $transaction = $this->beginTransaction($isolationLevel); $level = $transaction->level; try { $result = call_user_func($callback, $this); if ($transaction->isActive && $transaction->level === $level) { $transaction->commit(); } } catch (\Exception $e) { $this->rollbackTransactionOnLevel($transaction, $level); throw $e; } catch (\Throwable $e) { $this->rollbackTransactionOnLevel($transaction, $level); throw $e; } return $result; }
Cette méthode accepte une fonction de rappel et le niveau d'isolement de la transaction
De là, nous pouvons voir que bien que cela. La méthode résout le problème du code en double, il y en a encore plusieurs. Il y a deux problèmes qui n'ont pas été résolus :
Premièrement, l'exception levée par cette méthode doit être gérée en dehors de la réception. Nous ne pouvons pas la lancer directement, ce qui est très. hostile envers le client.
Deuxième : sans journalisation, même si un problème survient, il ne sera pas facile à éliminer.
Troisième : en fait, c'est toujours la première question. Si nous devons gérer chaque exception et imbriquer une couche de try...catch... en dehors de la méthode de transaction, alors cela ne semble pas être différent de ne pas encapsuler. il?
Selon le principe selon lequel les méthodes peuvent être étendues mais non modifiées, nous devons surcharger cette méthode dans notre propre méthode publique. Le code de surcharge est le suivant :
public static function TransactionExecute(callable $function,$level=null) { try{ \Yii::$app->db->transaction($function,$level); }catch (\Exception $e){ //记录日志 \Yii::error($e->getMessage()); //这里可以理解成抛出自定义的异常类。 (new self())->returnWayTip(1004, 'trans异常错误'); } }
Retournez ensuite à. comment passer les paramètres Question, nous pouvons utiliser des fermetures et poster un morceau de pseudo code, comme suit :
//执行事务 PublicFunction::TransactionExecute(function () use ($token_reward, $reward_info) { //业务代码 $token_reward->save(0); MsgHelper::send($reward_info['post_id'], MsgHelper::SOMEONE_FINISH_REWARD, $reward_info); });
Recommandations associées :
Comment php génère-t-il json ? Code de méthode pour que php génère json
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!