2017-02-20 16 views
1

Я создаю процедуры в базе данных PostgreSQL. Я читал о невозможности использования отката внутри этих процедур.Почему невозможно использовать Commit и rollback в процедуре PostgreSQL?

Почему?

Можно ли использовать фиксацию?

Я полагаю, что это связано с свойствами ACID, но что делать, если у нас есть две операции вставки в процедуре. Если второй не удается, второй получает откат?

спасибо.

+0

Во-первых, поскольку Postgres не имеет процедур, только функции. –

ответ

3

Postgres' overview дает подсказку, объясняя, как их функции отличаются от традиционных хранимых процедур:

Functions created with PL/pgSQL can be used anywhere that built-in functions could be used. For example, it is possible to create complex conditional computation functions and later use them to define operators or use them in index expressions.

Это делает неудобной для поддержки операций в рамках функций для каждой возможной ситуации. Из the docs:

Functions and trigger procedures are always executed within a transaction established by an outer query... However, a block containing an EXCEPTION clause effectively forms a subtransaction that can be rolled back without affecting the outer transaction.

Если вы должны были иметь две вставки в функции, то первый может быть завернуты в EXCEPTION блок, чтобы поймать любые ошибки и решить, если второй должен быть выполнен.

1

Вы правы. Вы не можете откатить транзакции, которые были запущены до процедуры из процедуры. Кроме того, транзакция также не может быть создана в рамках процедуры. Вы бы получить эту ошибку:

ERROR: cannot begin/end transactions in PL/pgSQL 
SQL state: 0A000 
Hint: Use a BEGIN block with an EXCEPTION clause instead. 

В этом состоянии ошибки, и, как упоминалось Мэтт, вы можете использовать блок исключения по существу выполнить откат. Из help:

When an error is caught by an EXCEPTION clause, the local variables of the PL/pgSQL function remain as they were when the error occurred, but all changes to persistent database state within the block are rolled back.

В качестве альтернативы, можно вызвать процедуру из транзакции, и профилирование, что обратно в случае необходимости.