set isolation level for postgresql stored procedures

后端 未结 4 913
温柔的废话
温柔的废话 2020-12-29 05:09

Hopefully a simple question, but one for which I haven\'t readily found a decent answer. I\'m reliably informed that stored procedures (user-defined DB functions) in Postgre

相关标签:
4条回答
  • 2020-12-29 05:25

    The language of the function makes no difference whatsoever.

    This fails:

    test=# create function test() returns int as $$
      set transaction isolation level serializable;
      select 1;
    $$ language sql;
    CREATE FUNCTION
    test=# select test();
    ERROR:  SET TRANSACTION ISOLATION LEVEL must be called before any query
    CONTEXT:  SQL function "test" statement 1
    

    Note that in your particular example, you could do this using a trigger on your first table. Just make sure that row count updates are done in a consistent order to avoid dead-locks, and you'll do fine in repeatable-read mode.

    I'm a fan of standards

    The PL/languages are platform specific.

    0 讨论(0)
  • 2020-12-29 05:29

    You can't do that.

    What you could do is have your function check what the current transaction isolation level is and abort if it's not the one you want. You can do this by running SELECT current_setting('transaction_isolation') and then checking the result.

    0 讨论(0)
  • 2020-12-29 05:35

    Transaction isolation means which changes made in other concurent transactions you can access.

    If you want to serialize execution you have to use locks.

    You may use after row trigger and update count. "UPDATE row_counts_table" will lock table and all transactions will be serialized. It is slow.

    In your example you have two statements. Insert is executed but update have to wait other transactions and count is not valid in this period.

    0 讨论(0)
  • 2020-12-29 05:41

    In PG your procedures aren't separate transactions. That is the stored procedure takes part in an existing transaction.

    BEGIN TRAN
    
    SELECT 1;
    SELECT my_proc(99);
    
    ROLLBACK TRAN;
    

    With that said you have to set the transaction level where the transaction starts which is outside the stored procedure.

    One option would be to configure the server to run in the isolation you mostly want to use and do a SET for the edge cases where it differs from your server setting.

    0 讨论(0)
提交回复
热议问题