1. Сообщите об ошибке: «Не могу поменять экземпляр PDO, находясь в рамках транзакции»
Запрашивая исходный код Laravel, вы можете подтвердить, что исключение добавлено в методе setPdo :
<? Phppublic function setpdo ($ pdo) {if ($ this-> transactions> = 1) {throw new Runtimeexception («Не удается поменять экземпляр PDO, находясь в пределах транзакции.»); } $ this-> pdo = $ pdo; вернуть $ this;}?> Буквально эта ошибка возникает из -за того, что соединение базы данных переключается при включении транзакции. Однако иногда эта ошибка может возникнуть, даже если код явно не переключает подключения базы данных. Например, когда возникает ошибка при выполнении оператора запроса, система будет использовать метод tryAgainIfCausedByLostConnection , чтобы определить, вызвана ли проблема потерянным соединением. Если это так, система будет воссоединиться с помощью метода reconnect . При повторном подключении система выполнит некоторые работы по очистке с помощью метода disconnect , и вызывается метод setPdo .
После прояснения причин и последствий вы, естественно, узнаете, как решить проблему: проверьте ситуацию в сети и подтвердите причину потери подключения к базе данных. Это может быть связано с тем, что есть проблема с определенным устройством, или это может быть из -за неправильных настроек timeout . Относительно dirty метод состоит в том, чтобы выполнить метод DB::reconnect() перед запросом и повторным подключением к базе данных.
2. Ошибка: «Не удается удалить задание: не_фунд»
Эта проблема на самом деле не имеет ничего общего с Ларавелом, но вызвана бобовым стеком в очереди.
Бобовый стебель
Чтобы решить эту проблему, вам нужно сначала понять жизненный цикл сообщения: когда в очереди помещается сообщение, оно входит в состояние READY , и в то же время оно будет связывать таймер TTR(time to run) чтобы указать время, когда сообщение разрешено запускать. Когда это сообщение потребляется, оно входит в RESERVED состояние. После потребления сообщение будет удалено. Если время потребления слишком длинное, длиннее TTR , система будет думать, что потребитель повесил трубку, а затем вернет сообщение из RESERVED состояния в READY состояние и передаст его другому потребителю для переработки. Следовательно, одно и то же сообщение может быть обработано несколькими потребителями. Первый потребитель, который обработал его, может нормально удалять сообщение, в то время как другие потребители сообщат об ошибке, которая не может быть удалена при удалении сообщения.
Решение очень простое. Во -первых, вы должны убедиться, что настройка TTR не может быть слишком маленьким; Во -вторых, Beanstalk фактически предоставляет специальную команду touch , чтобы решить проблему слишком долгого времени выполнения. Кроме того, иногда нам может потребоваться заблокировать уровень приложения, чтобы избежать ситуации, когда одно и то же сообщение обрабатывается несколькими потребителями одновременно.
3. Сообщите об ошибке: «Нет результатов запроса для модели»
Когда Ларавел читает и записывает разделение, потребитель может получить аналогичную ошибку при обработке сообщений. Команда очереди с потенциальными проблемами примерно следующим образом:
<? Phpclass foo Extends Command реализует самоотверженность, должен быть {Использовать InteractSwiethqueue, serializesmodels; Защищенный $ Bar; публичная функция __construct ($ id) {$ this-> bar = bar :: find ($ id); } публичная функция handle () {// $ this-> bar}}?> Очевидно, что когда Ларавел читает и записывает разделение, из-за задержки с мастером-рабов find быть не в состоянии запросить соответствующие данные. После того, как мы проанализировали его здесь, вполне вероятно, что метод написания будет изменен на следующее:
<? Phpclass foo Extends Command реализует самоотверженность, должен быть {Использовать InteractSwiethqueue, serializesmodels; Защищенный $ Bar; публичная функция __construct ($ id) {$ this-> bar = bar :: onwriteconnection ()-> find ($ id); } публичная функция handle () {// $ this-> bar}}?> То есть, запрос прикреплен к основному серверу с помощью метода Laravel's onWriteConnection , но на самом деле он недействителен. Суть проблемы состоит в том, что при десериализации система вызовет findOrFail с сервера.
<? PhppRoted Function getRestoredPropertyValue ($ value) {return $ value exanceforefitietifier? (Новая $ value-> class)-> findorfail ($ value-> id): $ value;}?> Поскольку мы не можем HACK структуру, onWriteConnection не имеет смысла. На самом деле, посмотрите на проблему с другой точки зрения. Пока вы сериализованы, убедитесь, что не используйте объекты базы данных в качестве атрибутов:
<? Phpclass foo Extends Command реализует самоотверженность, должен быть {Использовать InteractSwiethqueue, serializesmodels; Защищенный $ id; публичная функция __construct ($ id) {$ this-> id = $ id; } public function handle () {$ bar = bar :: OnwriteConnection ()-> find ($ this-> id); }}?>4. Резюме
Выше приведены несколько репрезентативных отчетов об ошибках и решения, с которыми я столкнулся при использовании Laravel. Если у вас есть какие -либо вопросы, пожалуйста, не стесняйтесь общаться друг с другом. Я надеюсь, что эта статья поможет всем, кто учится или работа.