首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >让postgres执行阻塞等待

让postgres执行阻塞等待
EN

Stack Overflow用户
提问于 2020-11-01 02:37:15
回答 1查看 123关注 0票数 0

我认为创建一个可以在plpgsql函数中使用的阻塞wait()可能很有趣(也很有用)。我让它工作了,但我不确定它是不是构思良好的。在使用datagrip时会出现一个有趣的问题。如果我从函数调用pg_wait():

代码语言:javascript
复制
select util.wait_test_func() into var   --this calls my pg_wait()

该函数将正常阻塞,直到我在不同的查询控制台窗口中发出通知。实际上,如果函数wait_test_function()调用我的pg_wait()三次,它就会正确阻塞三次,而我必须调用NOTIFY三次才能让函数完成。但是,一旦函数完成,如果我再次调用它,它会立即返回,而不会阻塞。这几乎就像是通知仍然在队列中,但我并不真的相信这是问题所在。如果我关闭datagrip查询控制台,打开一个新的控制台,并重新发出函数调用,它将再次正常工作,并正确阻塞。我可以一直重复这一点。新的查询控制台窗口中的第一个调用总是正确地阻塞,但随后的每个调用总是立即返回。这是我在postgres中的第一个C函数,所以我想知道我是不是做了一些根本错误的事情。谢谢你的帮助。我的代码如下。

C函数:

代码语言:javascript
复制
#ifdef WIN32
#include <windows.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>

#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif

#include "libpq-fe.h"
#include "postgres.h"
#include <limits.h>
#include <unistd.h>
#include <string.h>
#include "fmgr.h"
#include "utils/palloc.h"
#include "utils/elog.h"
#include "storage/bufpage.h"
#include "utils/builtins.h"

#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif

PG_FUNCTION_INFO_V1( pg_wait );

Datum pg_wait( PG_FUNCTION_ARGS );

Datum pg_wait( PG_FUNCTION_ARGS )
{
    PGconn     *conn;
    PGresult   *res;
    PGnotify   *notify;
    int         nnotifies;
    int         sock;
    fd_set      input_mask;
    
    char* conninfo = text_to_cstring(PG_GETARG_TEXT_PP(0));
    char* channel_name = text_to_cstring(PG_GETARG_TEXT_PP(1));
    
    char strlisten[50];
    strcpy(strlisten,  "LISTEN ");
    strcat(strlisten, channel_name);

    conn = PQconnectdb(conninfo);
    res = PQexec(conn, strlisten);
    PQclear(res);

    sock = PQsocket(conn);
    FD_ZERO(&input_mask);
    FD_SET(sock, &input_mask);
    select(sock + 1, &input_mask, NULL, NULL, NULL);
    PQconsumeInput(conn);
    if ((notify = PQnotifies(conn)) != NULL)
    {
       PQfreemem(notify);
       PQconsumeInput(conn);
    }
    PQfinish(conn);

    PG_RETURN_TEXT_P( PG_GETARG_TEXT_PP(1) );
}

util.wait_test_func()

代码语言:javascript
复制
create or replace function util.wait_test_func() returns integer
    parallel safe
    language plpgsql
as $$
DECLARE
    signal_name TEXT;
BEGIN
    RAISE NOTICE 'Before wait1';
    SELECT pg_wait('dbname=edw port=5432','CHANNEL1') INTO signal_name;
    RAISE NOTICE 'After wait1: %', signal_name;

    RAISE NOTICE 'Before wait2';
    SELECT pg_wait('dbname=edw port=5432','CHANNEL1') INTO signal_name;
    RAISE NOTICE 'After wait2: %', signal_name;

    RAISE NOTICE 'Before wait3';
    SELECT pg_wait('dbname=edw port=5432','CHANNEL1') INTO signal_name;
    RAISE NOTICE 'After wait3: %', signal_name;

    RETURN 0;
END
$$;

再次感谢您能提供的任何帮助。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-11-02 18:13:28

您是否尝试过将函数声明为VOLATILE

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

https://stackoverflow.com/questions/64625216

复制
相关文章

相似问题

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