web-dev-qa-db-fra.com

Utilisation multi-thread de SQLAlchemy

Je veux créer une interface de programmation d'application de base de données écrite en Python et en utilisant SQLAlchemy (ou tout autre connecteur de base de données s'il est dit que l'utilisation de SQLAlchemy pour ce type de tâche n'est pas la bonne façon de procéder) La configuration est un serveur MySQL fonctionnant sous Linux ou BSD et un logiciel Python fonctionnant sur une machine Linux ou BSD (étrangère ou locale).

Fondamentalement, ce que je veux faire est de générer un nouveau thread pour chaque connexion et le protocole serait personnalisé et assez simple, bien que pour chaque demande, je souhaite ouvrir une nouvelle transaction (ou session comme je l'ai lu), puis je dois valider la session. Le problème auquel je suis confronté en ce moment est qu'il y a une forte probabilité qu'une autre session se produise en même temps à partir d'une autre connexion.

Ma question ici est que dois-je faire pour gérer cette situation?

  • Dois-je utiliser un verrou pour qu'une seule session puisse s'exécuter en même temps?
  • Les sessions sont-elles réellement sans fil et j'ai tort de penser qu'elles ne le sont pas?
  • Existe-t-il une meilleure façon de gérer cette situation?
  • L'enfilage est-il la voie à ne pas suivre?
45
maaudet

Les objets de session ne sont pas thread-safe, mais sont thread-local . À partir des documents:

"L'objet Session est entièrement conçu pour être utilisé de manière non concurrente , ce qui, en termes de multithreading, signifie" seulement en un thread à la fois ".. un processus doit être en place pour que plusieurs appels à travers de nombreux threads n'obtiennent pas réellement la même session. Nous appelons cette notion stockage local de thread . "

Si vous ne voulez pas faire vous-même la gestion des threads et des sessions, SQLAlchemy a l'objet ScopedSession pour s'en occuper:

Par défaut, l'objet ScopedSession utilise threading.local () comme stockage, de sorte qu'un Session unique est conservé pour tous ceux qui font appel à ScopedSession registre, mais uniquement dans le cadre d'un seul thread. Les appelants qui appellent le Registre dans un thread différent obtiennent une instance de session locale à cet autre thread.

En utilisant cette technique, le ScopedSession fournit un moyen rapide et relativement simple de fournir un seul objet global dans une application qui peut être appelé à partir de plusieurs threads en toute sécurité.

Voir les exemples dans Sessions contextuelles/thread-local pour configurer vos propres sessions thread-safe:

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