SQLAlchemy 的多线程使用 [英] Multi-threaded use of SQLAlchemy

查看:61
本文介绍了SQLAlchemy 的多线程使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想制作一个用 Python 编写的数据库应用程序编程接口,并使用 SQLAlchemy(或任何其他数据库连接器,如果被告知使用 SQLAlchemy 执行此类任务不是好方法).设置是运行在 Linux 或 BSD 上的 MySQL 服务器和运行在 Linux 或 BSD 机器(外国或本地)上的 Python 软件.

I want to make a Database Application Programming Interface written in Python and using SQLAlchemy (or any other database connectors if it is told that using SQLAlchemy for this kind of task is not the good way to go). The setup is a MySQL server running on Linux or BSD and a the Python software running on a Linux or BSD machine (Either foreign or local).

基本上我想做的是为每个连接生成一个新线程,协议将是自定义的并且非常简单,尽管对于每个请求我想打开一个新事务(或我读过的会话)然后我需要提交会话.我现在面临的问题是,很有可能在同一时间从另一个连接发生另一个会话.

Basically what I want to do is spawn a new thread for each connections and the protocol would be custom and quite simple, although for each requests I would like to open a new transaction (or session as I have read) and then I need to commit the session. The problem I am facing right now is that there is high probability that another sessions happen at the same time from another connection.

我的问题是我应该怎么做来处理这种情况?

My question here is what should I do to handle this situation?

  • 我是否应该使用锁来同时运行一个会话?
  • 会话实际上是线程安全的吗?我错误地认为它们不是线程安全的?
  • 有没有更好的方法来处理这种情况?
  • 穿线是否行不通?

推荐答案

Session 对象线程安全,但线程本地.来自文档:

Session objects are not thread-safe, but are thread-local. From the docs:

"Session 对象完全设计为以非并发方式使用,就多线程而言,这意味着一次仅在一个线程中";.. 一些进程需要到位,以便跨多个线程的多次调用实际上不会获得同一个会话的句柄.我们称这个概念为线程本地存储."

"The Session object is entirely designed to be used in a non-concurrent fashion, which in terms of multithreading means "only in one thread at a time" .. some process needs to be in place such that mutltiple calls across many threads don’t actually get a handle to the same session. We call this notion thread local storage."

如果您不想自己管理线程和会话,SQLAlchemy 有 ScopedSession 对象来为您处理:

If you don't want to do the work of managing threads and sessions yourself, SQLAlchemy has the ScopedSession object to take care of this for you:

ScopedSession 对象默认使用 线程.local() 作为存储,以便为所有调用 ScopedSession 注册表的人维护一个 Session,但仅在单个线程的范围内.在不同线程中调用注册表的调用者会获得该其他线程本地的 Session 实例.

The ScopedSession object by default uses threading.local() as storage, so that a single Session is maintained for all who call upon the ScopedSession registry, but only within the scope of a single thread. Callers who call upon the registry in a different thread get a Session instance that is local to that other thread.

使用这种技术,ScopedSession 提供了一种快速且相对简单的方法,可以在应用程序中提供单个全局对象,可以安全地从多个线程调用.

Using this technique, the ScopedSession provides a quick and relatively simple way of providing a single, global object in an application that is safe to be called upon from multiple threads.

查看Contextual/Thread-local Sessions中的示例进行设置建立您自己的线程安全会话:

See the examples in Contextual/Thread-local Sessions for setting up your own thread-safe 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()

这篇关于SQLAlchemy 的多线程使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆