Подтвердить что ты не робот

Многопоточное использование SQLAlchemy

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

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

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

  • Должен ли я использовать блокировку, так что только один сеанс может работать одновременно?
  • Являются ли сеансы фактически потокобезопасными, и я ошибаюсь, думая, что это не так?
  • Есть ли лучший способ справиться с этой ситуацией?
  • Прокладывает ли он путь не к месту?
4b9b3361

Ответ 1

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

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

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

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

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

См. примеры в контекстных/локальных сеансах для настройки собственных потоковобезопасных сеансов:

# 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()