python - 使用 SQLAlchemy session 处理 Flask 和并发问题

标签 python postgresql session flask sqlalchemy

我正在使用 Flask 和 SQLAlchemy 开发 API,这就是我想要做的:

我有一个客户端应用程序,在多个平板电脑上运行,必须发送多个请求才能将内容添加到服务器。 但我不想在每个 API 请求结束时使用自动回滚(flask-sqlalchemy 的默认行为),因为数据的发送是通过多个请求完成的,就像这个非常简化的示例一样:

<强>1。 beginTransaction/?id=transactionId -> 为发出该请求的客户端打开一个新 session 。下面代码中的SessionManager.new_session()

<强>2。 addObject/?id=objectAid -> 将对象添加到 PostGreSQL 数据库并刷新

<强>3。 addObject/?id=objectBid -> 将对象添加到 PostGreSQL 数据库并刷新

<强>4。 commitTransaction/?id= transactionId -> 提交自 beginTransaction 以来发生的事情。下面代码中的SessionManager.commit()

这里的要点是,如果客户端应用程序在发送“commitTransaction”之前崩溃/失去连接,则不要将数据添加到服务器,从而防止服务器上的数据不完整。

由于我不想使用自动回滚,所以我不能真正使用flask-SQLAlchemy,所以我自己在我的flask应用程序中实现SQLAlchemy,但我不知道如何使用 session 。

这是我在 __ init __.py 中所做的实现:

db = create_engine('postgresql+psycopg2://admin:pwd@localhost/postgresqlddb',
                   pool_reset_on_return=False,
                   echo=True, pool_size=20, max_overflow=5)

Base = declarative_base()
metadata = Base.metadata
metadata.bind = db

# create a configured "Session" class
Session = scoped_session(sessionmaker(bind=db, autoflush=False))



class SessionManager(object):

    currentSession = Session()

    @staticmethod
    def new_session():
    #if a session is already opened by the client, close it
    #create a new session
        try:
            SessionManager.currentSession.rollback()
            SessionManager.currentSession.close()
        except Exception, e:
            print(e)

        SessionManager.currentSession = Session()
        return SessionManager.currentSession

    @staticmethod
    def flush():
        try:
            SessionManager.currentSession.flush()
            return True
        except Exception, e:
            print(e)
            SessionManager.currentSession.rollback()
            return False

    @staticmethod
    def commit():
    #commit and close the session
    #create a new session in case the client makes a single request without using beginTransaction/
        try:
            SessionManager.currentSession.commit()
            SessionManager.currentSession.close()
            SessionManager.currentSession = Session()
            return True
        except Exception, e:
            print(e)
            SessionManager.currentSession.rollback()
            SessionManager.currentSession.close()
            SessionManager.currentSession = Session()
            return False

但是现在当多个客户端发出请求时,API 不起作用,似乎每个客户端都共享同一个 session 。

我应该如何实现 session ,以便每个客户端都有不同的 session 并且可以同时发出请求?

谢谢。

最佳答案

您似乎希望多个 HTTP 请求共享一个事务。这是不可能的 - 与 HTTP 的无状态性质不兼容。

例如,请考虑一个客户端将打开事务并由于失去连接而无法关闭它。服务器无法知道这一点,并且会使该事务永远打开,可能会阻塞其他客户端。

使用事务来捆绑数据库请求是合理的,例如,当存在多个写入操作时,出于性能原因。或者保持数据库的一致性。但它始终必须在打开的同一个 HTTP 请求上提交或回滚。

关于python - 使用 SQLAlchemy session 处理 Flask 和并发问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29646832/

相关文章:

java - Hibernate:evict()一个持久对象,同时存储其更改

python - Matplotlib:生成多个具有不同和倒比例尺的双轴

python - 减少将 POStgreSQL 表引入具有 500000 行的 Pandas 的执行时间的替代方法?

python - 为什么分配给空列表(例如 [] = "")不会出错?

node.js - 如何高效地将 Postgres 数据从 Query 传输到 S3

sql - 如何在 Postgres 中构建一个函数来计算两个 "select count(*)"查询的百分比?

java - 无法理解 session 对象的行为

java - 在 WildFly 中的重新部署之间保持 HTTP session

python - 在没有 opencv 的情况下使用 python 实现 Sobel 运算符

python - 使用 scikit-learn 计算项目描述之间的余弦相似度