SQLAlchemy 的多线程使用

我想用 Python 编写一个数据库应用程序编程接口,并使用 SQLAlchemy (或任何其他数据库连接器,如果被告知使用 SQLAlchemy 完成这种任务并不是一个好方法的话)。该设置是一个运行在 Linux 或 BSD 上的 MySQL 服务器和一个运行在 Linux 或 BSD 机器(外部或本地)上的 Python 软件。

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

我的问题是,我该怎么处理这种情况?

  • 我是否应该使用一个锁,以便只有一个会话可以同时运行?
  • 会话真的是线程安全的吗? 我认为它们不是这样的想法是错误的吗?
  • 有没有更好的办法来处理这种情况?
  • 穿线的方式不去吗?
63103 次浏览

会话对象是 没有线程安全的,但是是 线程本地.来自文件:

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

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

默认情况下,ScopedSession对象使用 Local ()作为存储,因此对于所有调用 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()