Безопасно ли в postgres (неправильно) использовать временную (локальную для сеанса) последовательность в качестве локальной последовательности транзакции?

Я хочу иметь счетчик, который я буду сбрасывать на 0 каждый раз, когда начинается новая транзакция. Я хочу, чтобы значение этого счетчика использовалось в некоторых триггерах. Поскольку временные последовательности postgres являются локальными для сеанса, я могу использовать один в качестве своего счетчика, только если нет возможности запуска двух транзакций «параллельно» в одном сеансе. Безопасно ли это предположить в Postgres? (Что я имею в виду, что заставляет меня чувствовать себя неуверенным, так это ситуация, подобная автономным транзакциям в Oracle. В этом сценарии мой локальный объект сеанса будет совместно использоваться внешней транзакцией и внутренней автономной транзакцией, что разрушит локальность транзакции объекта, который я хочу .)

Я знаю, что могу использовать таблицу TEMP с ON COMMIT DROP или DELETE ROWS, но я хотел бы знать, будет ли достаточно временной последовательности, по крайней мере, в postgres.


person Paralife    schedule 06.12.2011    source источник
comment
Так в чем именно ваш вопрос? Это безопасно? недостаточно конкретен. Чего вы хотите достичь?   -  person Erwin Brandstetter    schedule 07.12.2011
comment
Я хотел бы знать, можно ли каким-либо образом получить доступ к локальному объекту сеанса более чем одной транзакцией одновременно. Я более подробно описал контекст моего вопроса. Извините, если не ясно.   -  person Paralife    schedule 07.12.2011


Ответы (1)


В настоящее время PostgreSQL не поддерживает параллельные или автономные транзакции, поэтому session == transaction и, следовательно, временная последовательность, локальная для сеанса, будет доступна только одной транзакции за раз.

На данный момент единственный способ смоделировать автономные транзакции в Pg — использовать dblink для создания нового подключения к базе данных. Поскольку это также устанавливает новый и независимый сеанс, вам не о чем беспокоиться из-за dblink.

В настоящее время это безопасно (если я правильно интерпретировал то, что вы хотите).

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

Вы могли бы сделать это сейчас, если бы захотели; используйте функцию txid_current(), чтобы получить идентификатор текущей транзакции.

Редактировать: Нет, txid не меняется в точках сохранения.

regress=> begin;
BEGIN
regress=> SELECT txid_current();
 txid_current 
--------------
       346947
(1 row)

regress=> savepoint test;
SAVEPOINT
regress=> SELECT txid_current();
 txid_current 
--------------
       346947
(1 row)

хотя я предполагаю, что это зависит от деталей реализации.

person Craig Ringer    schedule 07.12.2011
comment
Я думал об этом, но я этого не делал, потому что у меня сложилось впечатление, что txid меняется с точками сохранения. Разве это не правда? - person Paralife; 07.12.2011
comment
@Paralife: Кроме того, работа с динамическими идентификаторами затрудняет использование таких функций, как значения столбцов по умолчанию или нединамический SQL. - person Erwin Brandstetter; 07.12.2011
comment
txid не меняется между точками сохранения — см. выше. Если вас это беспокоит, вы можете создать идентификатор из txid и CURRENT_TIMESTAMP (поскольку это фиксируется при запуске txn). [Редактировать: это чепуха; txid все равно изменится. Вы не можете использовать просто метку времени, если два txns запускаются одновременно, вплоть до разрешения таймера. Фу. Просто полагайтесь на то, что txid не изменится, и хорошо тестируйте обновления!] Я не думаю, что это когда-либо будет особенно красиво, но вы можете обернуть его в простую функцию SQL, чтобы упростить использование по умолчанию и в нединамическом режиме. SQL, поскольку Эрвин упоминает об этом как о проблеме. - person Craig Ringer; 09.12.2011