【问题标题】:How to avoid dead lock while using advisory locks in postgresql在 postgresql 中使用咨询锁时如何避免死锁
【发布时间】:2017-05-04 23:56:52
【问题描述】:

我在 postgres 中使用 pg_advisory_lock 函数,如果它无法锁定特定键,则会阻塞/等待。我想知道是否有某种方法可以让这个超时?我找不到任何东西。如果没有,会话是否有办法强制释放由不同会话获得的锁?

谢谢!

【问题讨论】:

标签: postgresql


【解决方案1】:

如果您根本不想屏蔽,可以拨打pg_try_advisory_lock()

如果阻塞pg_advisory_lock() 调用确实导致死锁,它会在deadlock_timeout 设置指定的时间间隔(默认为一秒)后自动超时。您还可以通过设置lock_timeout(默认情况下禁用)来限制锁定等待时间——无论是否死锁。

请注意,触发这些超时中的任何一个都会引发错误,因此将错误处理包装在函数中可能很有用,例如:

CREATE FUNCTION pg_try_advisory_lock_with_timeout(key bigint) RETURNS boolean
SET lock_timeout TO '1s'
AS $$
BEGIN
  PERFORM pg_advisory_lock(key);
  RETURN true;
EXCEPTION
  WHEN lock_not_available OR deadlock_detected THEN
    RETURN false;
END;
$$
LANGUAGE plpgsql;

【讨论】:

    【解决方案2】:

    你可以试试idle_in_transaction_session_timeout

    使用已空闲的打开事务终止任何会话 长于指定的持续时间(以毫秒为单位)。这允许任何 该会话持有的锁将被释放和连接槽 被重复使用;它还允许仅对该事务可见的元组 被吸尘。有关这方面的更多详细信息,请参阅第 24.1 节。

    假设你运行Task A --> set lock resource X and set idle_in_transaction_session_timeout=1s --> 如果task A idle > 1s,则task A自动终止,lock X自动释放。那么任务B就可以拿到锁X了。

    这样可以避免资源X死锁。

    【讨论】:

      猜你喜欢
      • 2020-01-11
      • 2016-12-15
      • 1970-01-01
      • 1970-01-01
      • 2013-06-07
      • 2012-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多