我对从多个会话执行的 postgresql 函数有疑问。该函数foo
是在多个会话中同时创建的。这会导致登录功能同时执行。
在登录函数(见下文)中,有一个 if 语句IF token does not exists THEN
也同时执行。当然,由于令牌尚未创建,因此所有函数都是错误的。
这不是我想要的行为。是否有可能使该login
功能成为“线程安全”。像 Java 中的同步?
伪函数:
CREATE OR REPLACE FUNCTION foo() RETURNS VARCHAR AS
$body$
BEGIN
token = login();
result = doStuffWithTheLogin(token);
IF result = LoginFailed THEN
token = login(true);
RETURN 'RETRY';
END IF;
END;
$body$
LANGUAGE 'plpgsql'
SECURITY DEFINER;
登录功能:
CREATE OR REPLACE FUNCTION login(forceReload BOOLEAN) RETURNS VARCHAR AS
$body$
BEGIN
IF NOT forceReload THEN
token = getTokenFromStorage();
END IF;
IF token does not exists THEN
token = createNewToken();
saveTokenToStorage(token);
END IF;
RETURN token;
END;
$body$
LANGUAGE 'plpgsql'
SECURITY DEFINER;
我试过用表锁。但这并没有真正起到作用。该login
函数大约需要 2-3 秒才能完成,如果有 100 个 foo 任务,表将被锁定很长时间。