As per Postgres Documentation – Once prepared, a transaction can later be committed or rolled back with COMMIT PREPARED or ROLLBACK PREPARED, respectively. Those commands can be issued from any session, not only the one that executed the original transaction.
I am trying to import data from csv into database tables and for this, I am using the
COPY tablename [ ( column [, ...] ) ]
FROM { 'filename' }
all this is done in a shell script.
Now the issue is that I am executing psql command and passing this command as parameter via the -c option ( I start transaction via the command
prepare transaction 'some-id' in that command).
I want to create a Savepoint and rollback to it incase of any errors.
After a few other tasks in the shell script, I check for errors that the previous psql statement have produced and when I then try to rollback using the command
Prepared Rollback 'transaction-id' ( in separate psql command with sql statements )
It reports “No "transaction-id" found“
Am I getting the concept wrong or missing something in the process?
Is this happening because I am issuing psql command multiple time and each is resulting in new transaction ?
For your prepare to work, the
COPYandPREPAREmust be in the same session. Since your question lacks concrete commands, I’m assuming that when you write:You’re using different psql commands to COPY and PREPARE. This is wrong. Combine the COPY and PREPARE to the same session.
E.g.
The
PREPARE TRANSACTIONworks by writing the current transaction to the disc and exiting the transaction process in the current session. This is why you need aBEGIN: it starts the transaction you want to prepare. All commands you want to be affected by the prepeare must come after the transaction has been started (in your case the COPY command). When thePREPARE TRANSACTIONis issued, the transaction you are currently in is written to disk with the identifier you give. Any statements issued after the transaction is prepared are no longer part of the transaction. So doingBEGIN; PREPARE... ; COPYruns the COPY operation without a transaction.Here’s an example in psql shell:
Edit: You must enable prepared transactions in postgresql.conf:
If
max_prepared_transactionsis zero, psql reports that the transaction id is not found, but does not warn you about this feature being disabled. Psql gives a warning forPREPARE TRANSACTIONbut it’s easy to miss if your shell scripts print stuff after the prepare statement.