首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何使PostgreSQL函数原子化?

如何使PostgreSQL函数原子化?
EN

Stack Overflow用户
提问于 2014-09-27 23:50:50
回答 1查看 7.9K关注 0票数 3

假设我有一些如下所示的PostgreSQL函数:

CREATE FUNCTION insertSth() RETURNS void AS $$
BEGIN
    INSERT INTO ...;
END;

CREATE FUNCTION removeSthAfterSelect() RETURNS TABLE(...) AS $$
BEGIN
     SELECT id INTO some_id ...;
     RETURN QUERY SELECT * FROM ...;
     DELETE FROM ... WHERE id = some_id;
END;

CREATE FUNCTION justDeleteSth() RETURNS void AS $$
BEGIN
     DELETE FROM ...;
END;

CREATE FUNCTION justSelectSth() RETURNS TABLE(...) AS $$
BEGIN
     RETURN SELECT * FROM ...;
END;

据我所知,PostgresSQL函数insertSthjustDeleteSthjustSelectSth将自动执行(?)。因此,并行执行它们不会搞乱任何事情。

但是对于removeSthAfterSelect来说,如果有并行执行,可能是SELECT id INTO some_id ..找到了一些东西,然后同时另一个事务调用justDeleteSth并用id = someId删除了行,所以当事务继续时,它不会在这里删除任何东西:DELETE FROM ... WHERE id = some_id;,这意味着它把事情搞乱了。

真的是这样吗?有没有办法避免这个问题?例如,通过说removeSthAfterSelect应该被原子执行?

EN

回答 1

Stack Overflow用户

发布于 2019-06-10 19:32:13

通常可以使用锁定来实现所需的“原子”行为

例如:

BEGIN;  -- transaction
SELECT pg_advisory_xact_lock(123);  -- 123 is any big integer

-- do your "atomic" stuff here, other transactions
-- trying to acquire the same (123) lock will be waiting for it to be released

COMMIT;  -- transaction has ended, the locks are released automatically

缺点是这样的锁定块不会并行执行。有关详细信息,请参阅文档https://www.postgresql.org/docs/11/explicit-locking.html

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26076416

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档