2011-06-09 10 views
30

Quiero hacer una interfaz de programación de aplicaciones de base de datos escrito en Python y el uso de SQLAlchemy (o cualquier otro tipo de conectores de base de datos si se le dice que el uso de SQLAlchemy para este tipo de tarea no es la buena manera de ir) . La configuración es un servidor MySQL que se ejecuta en Linux o BSD y un software de Python que se ejecuta en una máquina Linux o BSD (ya sea extranjera o local).uso multi-hilo de SQLAlchemy

Básicamente lo que quiero hacer es generar un nuevo hilo para cada conexión y el protocolo sería personalizado y bastante simple, aunque para cada solicitud me gustaría abrir una nueva transacción (o sesión como he leído) y luego Necesito comprometer la sesión. El problema que estoy enfrentando ahora es que hay una gran probabilidad de que ocurran otras sesiones al mismo tiempo desde otra conexión.

Mi pregunta aquí es ¿qué debo hacer para manejar esta situación?

  • ¿Debo usar un candado para que solo una sesión se pueda ejecutar al mismo tiempo?
  • ¿Las sesiones son realmente seguras para hilos y me equivoco al pensar que no?
  • ¿Hay una mejor manera de manejar esta situación?
  • ¿Está enloqueciendo el camino para no ir?

Respuesta

33

objetos de sesión son no flujos seguros, pero son local de subprocesos. From the docs:

"El objeto Session está diseñado enteramente para ser utilizado en un no concurrente manera , que en términos de multihilo significa 'sólo en un hilo a la vez' .. algún proceso tiene que estar en su lugar de tal forma que las múltiples llamadas a través de muchos subprocesos en realidad no obtienen un identificador para la misma sesión. Llamamos a esta noción el almacenamiento local de subprocesos. "

Si no quiere hacer el trabajo de la gestión de las discusiones y sesiones de ti mismo, SQLAlchemy tiene el objeto ScopedSession a hacerse cargo de esto para usted:

El ScopedSession objeto de usos predeterminados [enhebrar .local()] como almacenamiento, de modo que se mantiene un único Session para todos los que invocan el registro ScopedSession, pero solo dentro del alcance de un único hilo. Las personas que llaman que llaman al registro en un subproceso diferente obtienen una instancia de sesión que es local para ese otro subproceso.

Usando esta técnica, el ScopedSession proporciona una forma rápida y relativamente simple de proporcionar un único objeto global en una aplicación que es segura para ser invocada desde múltiples hilos.

Véanse los ejemplos en Contextual/Thread-local Sessions para la creación de sus propias sesiones seguras para subprocesos:

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

No es 'session.remove()'? –

+4

@AllanRuin: si por 'sesión' te refieres' some_session' del ejemplo provisto, no. Un objeto 'session' no tiene método' remove'. En este caso, 'Session' es un objeto' scoped_session'. Su método 'remove' identifica la' sesión' actual y llama a su método 'close' antes de descartarlo. Explicado [en los documentos] (http://docs.sqlalchemy.org/en/latest/orm/contextual.html?highlight = scoped # sqlalchemy.orm.scoping.scoped_session.remove). – bfin

+2

enlace actualizado a los documentos: http://docs.sqlalchemy.org/en/latest/orm/contextual.html – Mahdi