Going off of this example, I am trying to lock someone's credit card account (row), check to see if they have enough money, and if they do, use it to pay. I need to lock it to prevent a condition where they have enough credit, but then it is used on another transaction and my program is left thinking it still does have enough credits.
At the terminal level I can accomplish this like so: I can open two psql
sessions in two terminals and I can issue a SELECT * FROM credit_card WHERE credit_card_number = 1234 FOR UPDATE;
command in one and then a SELECT * FROM credit_card FOR UDPATE
in the other (or something else like UPDATE credit_card SET credits = credits -99 WHERE credit_card_number = 1234
), and I can see that the former call blocks the latter call. However, when I do the same thing but in a function like so
CREATE OR REPLACE FUNCTION foo (p_credit_card_number BIGINT)
RETURNS VOID
AS $$
BEGIN
SELECT * FROM credit_card WHERE credit_card_number = p_credit_card_number FOR UPDATE
...
END
$$
LANGUAGE 'plpgsql';
I get the typical query has no destination for result data
error (eg. see here).
Question: How can I lock a specific row, or number of rows, while using SELECT ...FOR UPDATE
inside a Function while avoiding the above mentioned error?? If not possible, or not advisable, how else would I do this inside a Function?