Я использую Postgresql 9.0.5, и у меня есть задание cron, которое периодически читает вновь созданные строки из таблицы и накапливает их значение в сводной таблице, которая содержит почасовые данные.
Мне нужно получить последнюю версиюИдентификатор (последовательный), который зафиксирован, и все строки перед тем, как он будет зафиксирован.
Функция currval в этом случае не даст правильное значение, поскольку транзакция с вставкой currval может быть зафиксирована раньше, чем другие.Используя оператор SELECT, я вижу, что столбец Id не является непрерывным, потому что некоторые строки все еще не зафиксированы.
Here is some sample code I have used to test:
--test race condition
create table mydata(id serial,val int);
--run in thread 1
create or replace function insert_delay() returns void as $$
begin
insert into mydata(val) values (1);
perform pg_sleep(60);
end;
$$ language 'plpgsql';
--run in thread 2
create or replace function insert_ok() returns void as $$
begin
insert into mydata(val) values (2);
end;
$$ language 'plpgsql';
--run in thread 3
mytest=# select * from mydata; --SHOULD HAVE SEEN id = 1 and 2;
id | val
----+-----
2 | 2
(1 row)
Я даже попробовал некоторые операторы, подобные приведенному ниже;
select max(id) from mydata age(xmin) >= age(txid_snapshot_xmin(txid_current_snapshot())::text::xid);
Но в производственной линии (при выполнении транзакций большого объема) возвращаемый max (id) не будет двигаться вперед (даже все занятые транзакции завершены).Так что это тоже не работает.