Контекст: Я работаю над флеш-приложением, работающим на CherryPy, DB обрабатывается с использованием SQLAlchemy ORM.Как обрабатывать несколько запросов без SQLAlchemy сбой/повышение исключений?
Проблема:
приложение прекрасно работает и делает все, что я хочу, однако, если у меня есть страница, которая извлекает некоторые данные из БД и дисплеев, и я нажмите и удерживайте «Ctrl + R» или " F5" . То есть, постоянно обновлять страницу, делая так много запросов БД. Первые несколько идут хорошо, а затем ломаются. Следующие ошибки регистрируются:
(OperationalError) (2013, 'Lost connection to MySQL server during query')
Can't reconnect until invalid transaction is rolled back (original cause:
InvalidRequestError: Can't reconnect until invalid transaction is rolled back)
This result object does not return rows. It has been closed automatically.
(ProgrammingError) (2014, "Commands out of sync; you can't run this command now")
Там же еще одна ошибка, которая беспокоит меня (но не вошли в этот раз), это
dictionary changed size during iteration
Это происходит, когда я переборе запрос, используя значения, полученные для заполнения словаря. Словарь является локальным (область действия dict) для функции.
Подробнее:
Как я обработки сессий:
новый сеанс создается при вводе любой страницы, используйте эту сессию, чтобы выполнить все операции DB, и сессия закрыта правая перед рендерингом HTML. Технически это означает, что сфера сеанса такая же, как и HTTP-запрос.
Я делаю session.rollback()
только при наличии исключения, вызванного во время таблицы updating
или inserting
в таблицу. Нет rollback()
в течение любых query()
операций. Я уверен, что я совершил глупые ошибки или не делаю правильных действий.
Неограниченное количество обновлений, как это не похоже на сценарий, но нельзя игнорировать. Кроме того, я думаю, что поведение будет схожим, когда много пользователей используют его одновременно.
Как двигатель SQLAlchemy, sessionmaker был обработан:
sql_alchemy_engine = create_engine(self.db_string, echo=False, encoding="utf8", convert_unicode=True, pool_recycle=9)
sqla_session = sessionmaker(bind=sql_alchemy_engine)
Это сделано только один раз, как это рекомендуется в документации SQLA, и новый сеанс создается и возвращается sqla_session()
по мере необходимости.