1. Informe un error: "No se puede cambiar la instancia de PDO mientras está dentro de la transacción"
Al consultar el código fuente de Laravel, puede confirmar que la excepción se lanza en setPdo :
<? Función PhpPublic setPDO ($ PDO) {if ($ this-> transacciones> = 1) {Throw New RuntimeException ("No se puede cambiar la instancia de PDO mientras está dentro de la transacción"); } $ this-> pdo = $ pdo; devolver $ this;}?> Literalmente, este error ocurre porque la conexión de la base de datos se cambia cuando la transacción se enciende. Sin embargo, a veces, este error puede ocurrir incluso si el código no cambia explícitamente las conexiones de la base de datos. Por ejemplo, cuando ocurre un error al ejecutar una instrucción de consulta, el sistema usará el método de tryAgainIfCausedByLostConnection para determinar si el problema es causado por una conexión perdida. Si es así, el sistema se volverá a conectar a través del método reconnect . Al volver a conectarse, el sistema realizará algunos trabajos de limpieza a través del método disconnect , y se llama setPdo .
Después de aclarar las causas y las consecuencias, naturalmente sabrá cómo resolver el problema: verifique la situación de la red y confirme la causa de la pérdida de conexión de la base de datos. Esto puede deberse a que hay un problema con un determinado dispositivo, o puede deberse a la configuración inadecuada timeout . Un método relativamente dirty es ejecutar DB::reconnect() antes de consultar y reconectar a la base de datos.
2. Error: "No se puede eliminar el trabajo: Not_found"
Este problema en realidad no tiene nada que ver con Laravel, pero es causado por el servicio de cola Beanstalk.
Frijoles
Para resolver este problema, primero debe comprender el ciclo de vida de un mensaje: cuando se coloca un mensaje en la cola, ingresa al estado READY y, al mismo tiempo, asociará un temporizador TTR(time to run) para indicar el tiempo que el mensaje se permite ejecutar. Cuando se consume este mensaje, ingresa al estado RESERVED . Después del consumo, el mensaje se eliminará. Si el tiempo de consumo es demasiado largo, más largo que TTR , el sistema pensará que el consumidor ha colgado y luego devolver el mensaje del estado RESERVED al estado READY y entregarlo a otro consumidor para reprocesar. Por lo tanto, el mismo mensaje puede ser procesado por múltiples consumidores. El primer consumidor que lo ha procesado puede eliminar el mensaje normalmente, mientras que los otros consumidores informarán un error que no se puede eliminar al eliminar el mensaje.
La solución es muy simple. Primero, debe asegurarse de que TTR no pueda ser demasiado pequeña; En segundo lugar, Beanstalk en realidad proporciona un comando touch especial para resolver el problema del tiempo de ejecución demasiado largo. Además, a veces es posible que necesitemos bloquear en el nivel de aplicación para evitar la situación donde múltiples consumidores procesan el mismo mensaje al mismo tiempo.
3. Informe un error: "No hay resultados de consulta para el modelo"
Cuando se activa la separación de lectura y escritura de Laravel, un consumidor puede recibir un error similar al procesar mensajes. Un comando de cola con problemas potenciales es aproximadamente como sigue:
<? PhpClass foo extiende el comando implementa el autovaloramiento, debería ser cuidadoso {usar interactWithqueue, serializesmodels; protegido $ bar; función pública __construct ($ id) {$ this-> bar = bar :: find ($ id); } public Function Handle () {// $ this-> bar}}?> Es obvio que cuando la separación de lectura y escritura de Laravel se enciende, debido al retraso del esclavo maestro, find no ser capaz de consultar los datos correspondientes. Una vez que lo hayamos analizado aquí, es probable que el método de escritura se modifique a lo siguiente:
<? PhpClass foo extiende el comando implementa el autovaloramiento, debería ser cuidadoso {usar interactWithqueue, serializesmodels; protegido $ bar; función pública __construct ($ id) {$ this-> bar = bar :: onwriteConnection ()-> find ($ id); } public Function Handle () {// $ this-> bar}}?> Es decir, la consulta se fija en el servidor principal a través del método onWriteConnection de Laravel, pero en realidad no es válido. El quid del problema es que cuando la deserialización, el sistema llamará a findOrFail desde el servidor.
<? Función phprotected getRestoredPropertyValue ($ value) {return $ valor instancia de modelidentifier? (nuevo $ valor-> clase)-> findorFail ($ valor-> id): $ valor;}?> Debido a que no podemos HACK el marco, onWriteConnection no tiene sentido. De hecho, mire el problema desde una perspectiva diferente. Mientras esté en serie, asegúrese de no usar objetos de base de datos como atributos:
<? PhpClass foo extiende el comando implementa el autovaloramiento, debería ser cuidadoso {usar interactWithqueue, serializesmodels; protegido $ id; función pública __construct ($ id) {$ this-> id = $ id; } public Function Handle () {$ bar = bar :: onWriteConnection ()-> find ($ this-> id); }}?>4. Resumen
Los anteriores son varios informes de error representativos y soluciones que encontré al usar Laravel. Si tiene alguna pregunta, no dude en comunicarse entre sí. Espero que este artículo sea de ayuda para el estudio o el trabajo de todos.