Python SQlalchemy数据库级锁定

Python SQlalchemy数据库级锁定,python,postgresql,transactions,sqlalchemy,Python,Postgresql,Transactions,Sqlalchemy,我想知道是否有可能以某种方式锁定两个数据库表进行受保护的写操作或类似操作,以防止另一个应用程序在事务进行时修改这些表 我现在有这样的东西。表A、B和C之间具有一对多关系A->B和B->C。此函数从rabbitmq接收数据,并更新A、B和/或C(通常仅为C),或者在缺少时创建新行 Session=scoped_session(session_factory) try: foo = Session.query(A).filter(....).one() except NoResultFoun

我想知道是否有可能以某种方式锁定两个数据库表进行受保护的写操作或类似操作,以防止另一个应用程序在事务进行时修改这些表

我现在有这样的东西。表A、B和C之间具有一对多关系A->B和B->C。此函数从rabbitmq接收数据,并更新A、B和/或C(通常仅为C),或者在缺少时创建新行

Session=scoped_session(session_factory)
try:
    foo = Session.query(A).filter(....).one()
except NoResultFound:
    Session.remove()
    return

try:
    bar = Session.query(B).filter(......).one()
except NoResultFound:
    bar = B(field1=x, field2=y etc.)
    Session.add(bar)

try:
    xyzzy = Session.query(C).filter(...).order_by(...).limit(1).one()
except NoResultFound:
    xyzzy = C(.......)
    Session.add(xyzzy)

foo.fieldn = var1
bar.fieldn = var2
xyzzy.fieldn = var3
etc. 

Session.commit()
Session.remove()
这一切都很好。问题是,我有另一个程序(完全不同的python脚本)可以根据请求进行清理。它基本上删除了A、B和C中的所有内容。这同样有效

删除以下内容后,我的第一个程序立即崩溃:

sqlalchemy.orm.exc.StaleDataError: UPDATE statement 
on table 'C' expected to update 1 row(s); 0 were matched.
我可以捕获此异常并做出相应的反应,但我需要吗?如果我能在这两个程序中为一个短文件在数据库级别上保留A、B和C,这个问题就会得到解决。所有这些交易的持续时间都很短。我从sqlalchemy文档中了解到,会话也应该启动事务,但显然这意味着与数据库级别的事务不同

我的Session.query(C)找到了一行,但在第一个程序发出Session.commit()之前,另一个程序已经删除了它

20多年前,90年代的数据库和C I总是用DECLARE事务启动事务。。。为保护写保留A、B、C;或者类似的。现在这已经过去了,我只需要捕获异常,还是仍然可以从数据库级别的锁定中获益


Hannu

您可以使用以下命令执行显式锁定PostgreSQL:

但是,锁定三个表是解决问题的一种非常繁重的方法。既然你有一个1-m的关系,你可以考虑在<代码>行中锁定行< <代码>,而在每个事务的开始时:

SELECT * FROM A WHERE ... FOR UPDATE;
在SQLAlchemy中实现这一点的方法是:

foo = Session.query(A).filter(....).with_for_update().one()

您可以使用以下命令执行显式锁定PostgreSQL:

但是,锁定三个表是解决问题的一种非常繁重的方法。既然你有一个1-m的关系,你可以考虑在<代码>行中锁定行< <代码>,而在每个事务的开始时:

SELECT * FROM A WHERE ... FOR UPDATE;
在SQLAlchemy中实现这一点的方法是:

foo = Session.query(A).filter(....).with_for_update().one()

谢谢这就是我要找的。谢谢。这就是我要找的。