
Изоляция транзакций
~~~~~~~~~~~~~~~~~~~

Создаем базу данных и открываем два сеанса

      |  => create database db2;
      |  CREATE DATABASE

      |  => \c db2
      |  You are now connected to database "db2" as user "postgres".

      ||     => \c db2
      ||     You are now connected to database "db2" as user "postgres".

1.Изоляция и системный каталог
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Создаем функцию, возвращающую 1

      |  => create or replace function f() returns int \
      |  as $$ select 1; $$ language sql;
      |  CREATE FUNCTION

      |  => select f();
      |   f 
      |  ---
      |   1
      |  (1 row)
      |  

Во втором сеансе, внутри транзакции меняем функцию

      ||     => begin;
      ||     BEGIN

      ||     => create or replace function f() returns int \
      ||     as $$ select 2; $$ language sql;
      ||     CREATE FUNCTION

      ||     => select f();
      ||      f 
      ||     ---
      ||      2
      ||     (1 row)
      ||     

Не закрывая транзакцию во 2-м сеансе, вызываем функцию в 1-м сеансе

      |  => select f();
      |   f 
      |  ---
      |   1
      |  (1 row)
      |  

Фиксируем изменения и еще раз смотрим результат

      ||     => commit;
      ||     COMMIT

      |  => select f();
      |   f 
      |  ---
      |   2
      |  (1 row)
      |  

Многоверсионность в PostgreSQL распространяется на таблицы системного
каталога. В том числе и на pg_proc, где хранится исходный код функций.
Поэтому разные транзакции могут видеть и вызывать разные экземпляры
одной и той же функции.

2.Момент создания снимка
~~~~~~~~~~~~~~~~~~~~~~~~


      |  => create table t (id int);
      |  CREATE TABLE

Открываем транзакцию, но запросов к БД пока нет

      |  => begin isolation level repeatable read;
      |  BEGIN

Во втором сеансе добавляем строку в таблицу

      ||     => insert into t values (1);
      ||     INSERT 0 1

Проверяем содержимое таблицы в 1-м сеансе

      |  => select * from t;
      |   id 
      |  ----
      |    1
      |  (1 row)
      |  

      |  => commit;
      |  COMMIT

Первая выполненная команда видит изменения, сделанные после старта 
транзакции.
Это происходит потому, что для REPEATABLE READ и SERIALIZABLE транзакций, 
снимок данных создается не при открытии транзакции, 
а при выполнении первого запроса к БД.

      |  => \q
      ||     => \q
