在多线程环境中使用SQLAlchemy执行事务

时间:2018-10-17 17:17:09

标签: python postgresql sqlalchemy flask-sqlalchemy

我正在开发一个使用Flask,SQLAlchemy和PostgreSQL的应用程序。我必须编写一个事务,对数据库执行多个查询。

def exec_query_1():
    with db.engine.connect() as connection:
        connection.execute(#some-query)

def exec_query_2():
    with db.engine.connect() as connection:
        connection.execute(#some-query)

def exec_query_3():
    with db.engine.connect() as connection:
        connection.execute(#some-query)

def execute_transaction():
    with db.engine.connect() as connection:
        with connection.begin() as transaction:
            exec_query_1()
            exec_query_2()
            exec_query_3()

鉴于应用程序是多线程的,此代码是否可以按预期工作? 如果是,怎么办?如果没有,那么使它工作的正确方法是什么?

1 个答案:

答案 0 :(得分:2)

即使在单个线程中,代码也无法按预期工作。在函数中打开的连接与execute_transaction()中使用的连接是独立的 1 ,并且具有自己的事务。您应该安排代码,以便函数接收与正在进行的事务的连接作为参数:

def exec_query_1(connection):
    connection.execute(#some-query)

def exec_query_2(connection):
    connection.execute(#some-query)

def exec_query_3(connection):
    connection.execute(#some-query)

def execute_transaction():
    with db.engine.connect() as connection:
        with connection.begin() as transaction:
            exec_query_1(connection)
            exec_query_2(connection)
            exec_query_3(connection)

请记住,连接不是线程安全的,因此不要在线程之间共享它们。 "When do I construct a Session, when do I commit it, and when do I close it?"是一本不错的书,大约是Session的意思。

1 可能取决于池配置。