Quoting Chris Darroch <[EMAIL PROTECTED]>:
So, like this:
switch (trans->mode) {
case APR_DBD_TRANSACTION_COMMIT:
res = PQexec(trans->handle->conn, "COMMIT");
break;
case APR_DBD_TRANSACTION_COMMIT_ON_SUCCESS:
if (trans->errnum) {
trans->errnum = 0;
res = PQexec(trans->handle->conn, "ROLLBACK");
} else
res = PQexec(trans->handle->conn, "COMMIT");
break;
case APR_DBD_TRANSACTION_ROLLBACK:
res = PQexec(trans->handle->conn, "ROLLBACK");
break;
}
Right. That was my understanding of it as well.
Currently the API relies on all query/select call status codes to
determine if the transaction as a whole is going to be success or
failure - it doesn't determine that from the status code of
apr_dbd_transaction_end (its status code is relevant to that function
call only). In fact, once the transaction goes bad, subsequent calls
to query/select don't actually execute anything within the database -
they just return bad status code. In other words, by the time we
reached transaction end, we must have been checking the error codes,
otherwise we're screwed for sure and things will rollback anyway.
So, I would be in favour of keeping that logic - the caller needs to
know *before* calling transaction end if there is a chance of the
whole transaction succeeding or not. And mode can also be chosen
explicitly if everything is OK. Something like:
- begin transaction
- all OK?
- if yes, start loop
- begin loop
- query/select
- all OK?
- if not, exit loop (no need to change mode here!)
- if yes, do nothing
- results as expected?
- if not, set mode rollback, exit loop (explicit rollback!)
- end loop
- end transaction
- all OK?
- if not, notify upstream or maybe retry
Put differently, the need for explicit rollback is really based on
some unexpected result from query/select - not a bad status code. On
bad status code there is nothing that can be done to save the
transaction (bar savepoints, which the current logic probably won't
even withstand, because we can't force transaction status code change
using the API) - rollback is the only option.
That's why I was thinking that we only need two modes: COMMIT and
ROLLBACK. SQL experts, please feel free to tear my argument to shreds
:-)
--
Bojan