我有一个需要在多个大表上执行长时间更新的函数.在更新期间,一次需要将2-3个表锁定在EXCLUSIVE模式下.
由于不是所有的表都需要同时锁定,理想情况下我只想锁定那些我当时正在更新的表,然后在我完成后删除锁.
例如.
-- Lock first pair of tables LOCK TABLE tbl1_a IN EXCLUSIVE MODE; LOCK TABLE tbl1_b IN EXCLUSIVE MODE; -- Perform the update on tbl1_a and tbl1_b -- Release the locks on tbl1_a and tbl1_b -- HOW??? -- Proceed to the next pair of tables LOCK TABLE tbl2_a IN EXCLUSIVE MODE; LOCK TABLE tbl2_b IN EXCLUSIVE MODE;
不幸的是,在plpgsql中没有相应的UNLOCK语句.删除LOCK的常规方法是COMMIT事务,但这在函数内部是不可能的.
这有什么解决方案吗?在函数完成之前显式释放锁的某种方法?或者运行某种子事务(也许通过在单独的函数中运行每个更新)?
UPDATE
没有办法. Postgres中的函数是原子的(总是在事务中),并且在事务结束时释放锁.而且还没有自主交易.
你或许可以用advisory locks来解决这个问题.但这些并不是一回事.所有竞争交易都必须发挥作用.不知道咨询锁的并发访问将破坏该方.
关于dba.SE的代码示例:
或者你可能会遇到与dblink“作弊”自治交易的地方:
> How do I do large non-blocking updates in PostgreSQL?
> Does Postgres support nested or autonomous transactions?
或者您重新评估您的问题并将其拆分为几个单独的交易.