Let's say I need to run some queries AND send an email in an atomic way.
A typical example is for a user sign-up form, I need to create the user and send the welcome email.
I can use a transaction :
begin transaction
create user
if creation failed, rollback transaction, bailout
send email
if email sending failed, rollback transaction, bailout
commit transaction
but, in PostgreSQL, a commit can fail (for example when using DEFERRED constraints).
So the solution would be to use a two-phase commit :
begin transaction
create user
PREPARE TRANSACTION
if creation failed, rollback transaction, bailout
send email
if email sending failed, rollback transaction, bailout
COMMIT PREPARED // this one is guaranteed to work by Postgres
but the Postgres doc says : It is unwise to leave transactions in the prepared state for a long time.
Moreover :
The intended usage of the feature is that a prepared transaction will normally be committed or rolled back as soon as an external transaction manager has verified that other databases are also prepared to commit.
So,
Is sending an email too much time ?
What problems could arise if we do so ?
What would be an acceptable timeout if it takes too long ?
Are database locks different in prepared state than in idle state (ie. before the commit) ?