Postgresql 的 SQLalchemy 显式锁定 table
Sqlalchemy explicit locking of Postgresql table
我正在尝试使用此 sqlalchemy 命令显式锁定 postgres table:
db.engine.execute('BEGIN; LOCK TABLE database_version IN ACCESS EXCLUSIVE MODE;')
执行后,如果我进入数据库客户端并 运行:
select * from pg_catalog.pg_locks;
不存在任何 ACCESS EXCLUSIVE 锁。
如果相反,我 运行 第一个命令,但是从数据库客户端内部,它按预期工作。
尝试从 sqlalchemy 获取 table 锁是否无法正常工作是有原因的吗?
理想情况下,我希望一次只有一个进程能够从 database_version table 中查询和插入。
所以事实证明我需要从会话对象开始嵌套事务,而不是尝试 BEGIN
使用直接 SQL。
db.session.begin_nested()
db.session.execute('LOCK TABLE database_version IN ACCESS EXCLUSIVE MODE;')
然后,我插入新行:
new_version = DatabaseVersion(version=version + 1)
db.session.add(new_version)
db.session.commit()
然后最后再次提交以关闭嵌套事务:
db.session.commit()
with_lockmode("...") 现在已在 sqlalchamy 中弃用,请参阅此处的参考资料:
https://kite.com/python/docs/sqlalchemy.orm.Query.with_lockmode
现在的解决方案是使用:
session.query(database_version).with_for_update()
我正在尝试使用此 sqlalchemy 命令显式锁定 postgres table:
db.engine.execute('BEGIN; LOCK TABLE database_version IN ACCESS EXCLUSIVE MODE;')
执行后,如果我进入数据库客户端并 运行:
select * from pg_catalog.pg_locks;
不存在任何 ACCESS EXCLUSIVE 锁。
如果相反,我 运行 第一个命令,但是从数据库客户端内部,它按预期工作。
尝试从 sqlalchemy 获取 table 锁是否无法正常工作是有原因的吗?
理想情况下,我希望一次只有一个进程能够从 database_version table 中查询和插入。
所以事实证明我需要从会话对象开始嵌套事务,而不是尝试 BEGIN
使用直接 SQL。
db.session.begin_nested()
db.session.execute('LOCK TABLE database_version IN ACCESS EXCLUSIVE MODE;')
然后,我插入新行:
new_version = DatabaseVersion(version=version + 1)
db.session.add(new_version)
db.session.commit()
然后最后再次提交以关闭嵌套事务:
db.session.commit()
with_lockmode("...") 现在已在 sqlalchamy 中弃用,请参阅此处的参考资料: https://kite.com/python/docs/sqlalchemy.orm.Query.with_lockmode
现在的解决方案是使用:
session.query(database_version).with_for_update()