1. Signaler une erreur: "Impossible d'échanger l'instance APDE lors de la transaction"
En interrogeant le code source de Laravel, vous pouvez confirmer que l'exception est lancée dans setPdo :
<? Phppublic Fonction setpDo ($ pDo) {if ($ this-> transactions> = 1) {lancez new RuntimeException ("Impossible d'échanger l'instance PDO lors de la transaction."); } $ this-> PDO = $ PDO; retourner $ ceci;}?> Littéralement, cette erreur se produit car la connexion de la base de données est commise lorsque la transaction est activée. Cependant, parfois, cette erreur peut se produire même si le code ne change pas explicitement les connexions de la base de données. Par exemple, lorsqu'une erreur se produit lors de l'exécution d'une instruction de requête, le système utilisera la méthode tryAgainIfCausedByLostConnection pour déterminer si le problème est causé par une perte de connexion. Si c'est le cas, le système se reconnectera via la méthode reconnect . Lors de la reconnexion, le système effectuera un travail de nettoyage via la méthode disconnect et setPdo est appelée.
Après avoir clarifié les causes et les conséquences, vous saurez naturellement comment résoudre le problème: vérifier la situation du réseau et confirmer la cause de la perte de connexion de la base de données. Cela peut être dû au fait qu'il y a un problème avec un certain appareil, ou cela peut être dû aux paramètres timeout inappropriés. Une méthode relativement dirty consiste à exécuter DB::reconnect() avant de l'interroger et de se reconnecter à la base de données.
2. Erreur: "Impossible de supprimer le travail: not_found"
Ce problème n'a en fait rien à voir avec Laravel, mais est causé par le service de service de file d'attente.
Haricot
Pour résoudre ce problème, vous devez d'abord comprendre le cycle de vie d'un message: Lorsqu'un message est placé dans la file d'attente, il entre dans l'état READY , et en même temps, il associera une minuterie TTR(time to run) pour indiquer l'heure à laquelle le message est autorisé à fonctionner. Lorsque ce message est consommé, il entre dans l'état RESERVED . Après la consommation, le message sera supprimé. Si le temps de consommation est trop long, plus long que TTR , le système pensera que le consommateur a raccroché, puis renvoie le message de RESERVED à READY et le remettez à un autre consommateur pour retraiter. Par conséquent, le même message peut être traité par plusieurs consommateurs. Le premier consommateur qui l'a traité peut supprimer le message normalement, tandis que les autres consommateurs signaleront une erreur qui ne peut pas être supprimée lors de la suppression du message.
La solution est très simple. Tout d'abord, vous devez vous assurer que TTR ne peut pas être trop petit; Deuxièmement, Beanstalk fournit en fait une commande touch spéciale pour résoudre le problème du temps d'exécution trop long. De plus, nous pouvons parfois devoir nous verrouiller au niveau de l'application pour éviter la situation où le même message est traité par plusieurs consommateurs en même temps.
3. Signaler une erreur: "Aucun résultat de requête pour le modèle"
Lorsque Laravel Read and Write Séparation est activé, un consommateur peut recevoir une erreur similaire lors du traitement des messages. Une commande de file d'attente avec des problèmes potentiels est à peu près la suivante:
<? PHPClass Foo étend la commande implémente l'auto-handicap, devrait-il faire {utiliser des interactionswithqueue, serializesModels; Bar $ protégé; Fonction publique __Construct ($ id) {$ this-> bar = bar :: find ($ id); } Fonction publique Handle () {// $ this-> bar}}?> Il est évident que lorsque Laravel a lu et écrit la séparation est activée, en raison du retard maître-esclave, find peut ne pas être en mesure d'interroger les données correspondantes. Une fois que nous l'avons analysé ici, il est probable que la méthode d'écriture sera modifiée à ce qui suit:
<? PHPClass Foo étend la commande implémente l'auto-handicap, devrait-il faire {utiliser des interactionswithqueue, serializesModels; Bar $ protégé; Fonction publique __Construct ($ id) {$ this-> bar = bar :: onwriteConnection () -> find ($ id); } Fonction publique Handle () {// $ this-> bar}}?> C'est-à-dire que la requête est épinglée sur le serveur principal via la méthode de Laravel onWriteConnection , mais elle est en fait invalide. Le nœud du problème est que lorsque la désérialisation, le système appellera findOrFail du serveur.
<? Fonction PHPProtected getRestoredPropertyValue ($ Value) {return $ valeur instanceof ModelIdentifier? (new $ value-> class) -> findorfail ($ value-> id): $ value;}?> Parce que nous ne pouvons pas HACK le framework, onWriteConnection n'a aucun sens. En fait, regardez le problème sous une perspective différente. Tant que vous êtes sérialisé, assurez-vous de ne pas utiliser les objets de base de données comme attributs:
<? PHPClass Foo étend la commande implémente l'auto-handicap, devrait-il faire {utiliser des interactionswithqueue, serializesModels; protégé $ id; Fonction publique __Construct ($ id) {$ this-> id = $ id; } Fonction publique Handle () {$ bar = bar :: onwriteConnection () -> find ($ this-> id); }}?>4. Résumé
Ce qui précède sont plusieurs rapports d'erreur et solutions représentatifs que j'ai rencontrés lors de l'utilisation de Laravel. Si vous avez des questions, n'hésitez pas à communiquer entre elles. J'espère que cet article sera d'une aide à l'étude ou au travail de chacun.