Многопоточное использование SQLAlchemy - PullRequest
44 голосов
/ 09 июня 2011

Я хочу создать интерфейс программирования приложений баз данных, написанный на Python и использующий SQLAlchemy (или любые другие коннекторы баз данных, если сказано, что использование SQLAlchemy для такого рода задач не является хорошим способом).Это сервер MySQL, работающий на Linux или BSD, и программное обеспечение Python, работающее на компьютере с Linux или BSD (иностранным или локальным).

В основном я хочу создать новый поток для каждого соединенияи протокол будет нестандартным и довольно простым, хотя для каждого запроса я хотел бы открыть новую транзакцию (или сеанс, как я прочитал), а затем мне нужно зафиксировать сеанс.Проблема, с которой я сейчас сталкиваюсь, заключается в том, что существует высокая вероятность того, что одновременно с другим соединением будут происходить другие сеансы.

Мой вопрос здесь заключается в том, что мне следует сделать, чтобы справиться с этой ситуацией?

  • Должен ли я использовать блокировку, чтобы одновременно мог выполняться только один сеанс?
  • Действительно ли сеансы поточно-ориентированы, и я ошибаюсь, полагая, что это не так?
  • есть лучший способ справиться с этой ситуацией?
  • Не стоит ли заняться многопоточностью?

1 Ответ

47 голосов
/ 16 августа 2013

Объекты сеанса не поточно-ориентированы, но локально-поточно . Из документов:

"Объект Session полностью предназначен для использования в режиме non-concurrent , что с точки зрения многопоточности«только в одном потоке за один раз» ... необходимо, чтобы какой-то процесс выполнялся таким образом, чтобы множественные вызовы во многих потоках фактически не обрабатывали один и тот же сеанс. Мы называем это понятие локальное хранилище потока . "

Если вы не хотите выполнять работу по управлению потоками и сеансами самостоятельно, SQLAlchemy имеет объект ScopedSession, который позаботится об этом за вас:

Объект ScopedSession по умолчанию использует [threading.local ()] в качестве хранилища, так что один Session поддерживается для всех, кто обращается к реестру ScopedSession, но только в рамках одного потока.Вызывающие, которые обращаются к реестру в другом потоке, получают экземпляр Session, который является локальным для этого другого потока.

Используя эту технику, ScopedSession обеспечивает быстрый и относительно простой способ предоставления одного глобального объектав приложении, которое безопасно вызывать из нескольких потоков.

См. примеры в Contextual / Thread-local Sessions для настройки ваших собственных потоковобезопасных сеансов:

# set up a scoped_session
from sqlalchemy.orm import scoped_session
from sqlalchemy.orm import sessionmaker

session_factory = sessionmaker(bind=some_engine)
Session = scoped_session(session_factory)

# now all calls to Session() will create a thread-local session
some_session = Session()

# you can now use some_session to run multiple queries, etc.
# remember to close it when you're finished!
Session.remove()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...