使用psycopg2使用ACCESS EXCLUSIVE锁定表

时间:2018-05-14 07:37:26

标签: postgresql locking psycopg2

我正在尝试使用带有Django&的psycopg2显式锁定表格。 Heroku,因此在此期间任何其他服务器/工作者都无法访问它。

我读到ACCESS EXCLUSIVE完全符合我的需要。但是,我只发现了explanations about when it is automatically called (with DROP TABLE, VACUUM FULL, etc.;但是我不知道如何明确地称它,按照我的意愿锁定桌子。

我尝试了以下内容:

 with SQL().con2db() as conn:

   cur = conn.cursor()

    lock_query = 'ACCESS EXCLUSIVE {tbl_name}'.format(tbl_name=tbl_name)
    cur.execute(lock_query, )

    #do whatever

    cur.close()

但是我收到了一个错误:

psycopg2.ProgrammingError: syntax error at or near "ACCESS"
LINE 1: ACCESS EXCLUSIVE table_name

我怎样才能做到这一点?

2 个答案:

答案 0 :(得分:1)

要显式锁定表,请使用SQL语句LOCK

由于锁只保留到数据库事务结束,因此您必须显式启动和结束事务。

由于这会大大影响并发性,因此您应该考虑是否有更好的方法来解决您的问题。

答案 1 :(得分:0)

经过一番进一步调查后,我发现this post谈到了咨询锁:

  

咨询锁

     

Postgres提供了一种创建锁的方法   应用定义的含义。这些被称为咨询锁,因为   系统不强制使用它 - 由应用程序决定   正确使用它们。

     

在Postgres中有两种获取咨询锁的方法:在会话中   级别或交易级别。一旦在会话级别获得,   在明确发布或会话结束之前,将保持咨询锁定。   与标准锁请求不同,会话级咨询锁请求可以   不尊重事务语义:在事务期间获取的锁   稍后回滚的内容仍将在回滚后保留,   同样,即使呼叫交易,解锁也是有效的   以后失败了。可以通过拥有多次获取锁   处理;对于每个完成的锁定请求,必须有相应的   在实际释放锁之前解锁请求。事务级   另一方面,锁定请求的行为更像是常规锁定   请求:它们会在结束时自动释放   事务,并没有明确的解锁操作。这种行为   通常比会话级行为更方便   短期使用咨询锁。会话级和   对同一个咨询锁标识符的事务级锁请求   将以预期的方式阻止对方。如果会话已经存在   一个给定的咨询锁,它的额外请求将始终成功,   即使其他会议正在等待锁定;这种说法是对的   无论现有的锁定保持和新请求是否在   会话级别或事务级别。完整的功能列表   可以在documentation中找到操纵咨询锁。

     

...

-- Transaction 1
BEGIN;

SELECT pg_advisory_xact_lock(1);
-- Some work here

我不确定这是如何工作的,因为我没有指定我想要阻止的表,但它似乎可以完成这项工作。

with SQL().con2db() as conn:

    cur = conn.cursor()

    lock_query = 'SELECT pg_advisory_xact_lock(1);'
    cur.execute(lock_query, )

    #do whatever

    cur.close()

任何进一步的解释,以更好地理解它或替代方法是非常受欢迎的。