python - SQLalchemy 数据库级锁定

标签 python postgresql transactions sqlalchemy

我想知道是否有可能以某种方式锁定几个数据库表以进行 protected 写入或类似操作,以防止另一个应用程序在事务处理过程中修改这些表?

我现在有这样的东西。表 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.

我可以捕捉到这个异常并做出相应的 react ,但我需要这样做吗?如果我可以在两个程序中都在数据库 级别为短文件保留 A、B 和 C,那么这个问题就会得到解决。所有这些交易的持续时间都很短。我从 sqlalchemy 文档中了解到 session 也应该启动事务,但显然这意味着与数据库级别的事务不同。

似乎发生的情况是我的 Session.query(C) 找到了一行,但在第一个程序发出 Session.commit() 之前,另一个程序已将其删除。

20 多年前,对于 90 年代的数据库和 C,我总是以 DECLARE TRANSACTION 开始一个事务......为 PROTECTED WRITE 保留 A、B、C;或类似的东西。现在它消失了吗,我只需要捕获异常,或者我仍然可以从数据库级别的锁定中受益?

汉奴

最佳答案

您可以使用 LOCK command 执行显式锁定 PostgreSQL :

LOCK A, B, C IN ACCESS EXCLUSIVE MODE;

但是,锁定三个表是解决问题的一种非常笨拙的方法。由于您有 1-m 关系,您可以考虑在每个事务开始时锁定 A 中的行:

SELECT * FROM A WHERE ... FOR UPDATE;

在 SQLAlchemy 中执行此操作的方法是:

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

关于python - SQLalchemy 数据库级锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43473559/

相关文章:

python - 使用 irc.bot.SingleServerIRCBot 保留线程(与 twitch 一起使用)

Python GTK更新标签

Python获取有关组策略的信息

Python 分组显示列

postgresql9.1 突然无法连接到服务器 : No route to host

Android FragmentManager beginTransaction.add 添加 fragment 到隐藏容器

超过 100 万行的 SQL Server BULK INSERT - 需要性能改进

SQL WHERE条件为列表,列类型为数组

sql - 为什么这个查询需要聚合?

javascript - 内在气体太低并超出区 block 限制