Chris Angelico
2011-11-23 04:58:10 UTC
I'm building an application that gets commands from the database, and
stores its results in the database. I want to do the entire job in a
single transaction, so that if the database or application dies, the
command will still be waiting there (ie roll back the 'DELETE FROM
jobs WHERE ID=123' query); but if I get any sort of error during
processing (be it SQL error, exception thrown, or something detected
at high level), I want to roll back the entire task *except* for the
deletion of the job - to prevent infinite loops processing failing
commands. The source shows that subtransaction is backed by SAVEPOINT
/ RELEASE SAVEPOINT / ROLLBACK TO SAVEPOINT, which ought to be what
I'm after.
Currently, what I'm looking at is:
work trans(conn);
trans.query("delete from jobs where blah");
try {
subtransaction subtrans(conn);
subtrans.exec("do the actual work");
if (something_is_invalid) ; //???
subtrans.exec("do more work");
} catch(){}
//if we get here, everything's fine
trans.commit();
According to the example in the docs, a subtransaction doesn't need to
be committed. But it doesn't show rolling back the subtrans on error;
is it automatically rolled back, or was that quietly ignored because
there was only one query in the subtrans?
I'm also not sure what the best way to handle the
"something_is_invalid" part. The subtransaction code is all in a
function, so I could use 'return' there; or I could throw an
exception. The docs are a bit scanty on the subject of exceptions - do
SQL errors do anything special to the subtrans? What about other
exceptions?
I'm pretty sure pqxx::subtransaction is what I'm looking for, but I'd
like to hear from someone who's used the feature first.
Thanks in advance!
Chris Angelico
stores its results in the database. I want to do the entire job in a
single transaction, so that if the database or application dies, the
command will still be waiting there (ie roll back the 'DELETE FROM
jobs WHERE ID=123' query); but if I get any sort of error during
processing (be it SQL error, exception thrown, or something detected
at high level), I want to roll back the entire task *except* for the
deletion of the job - to prevent infinite loops processing failing
commands. The source shows that subtransaction is backed by SAVEPOINT
/ RELEASE SAVEPOINT / ROLLBACK TO SAVEPOINT, which ought to be what
I'm after.
Currently, what I'm looking at is:
work trans(conn);
trans.query("delete from jobs where blah");
try {
subtransaction subtrans(conn);
subtrans.exec("do the actual work");
if (something_is_invalid) ; //???
subtrans.exec("do more work");
} catch(){}
//if we get here, everything's fine
trans.commit();
According to the example in the docs, a subtransaction doesn't need to
be committed. But it doesn't show rolling back the subtrans on error;
is it automatically rolled back, or was that quietly ignored because
there was only one query in the subtrans?
I'm also not sure what the best way to handle the
"something_is_invalid" part. The subtransaction code is all in a
function, so I could use 'return' there; or I could throw an
exception. The docs are a bit scanty on the subject of exceptions - do
SQL errors do anything special to the subtrans? What about other
exceptions?
I'm pretty sure pqxx::subtransaction is what I'm looking for, but I'd
like to hear from someone who's used the feature first.
Thanks in advance!
Chris Angelico