On Sunday 30 April 2006 23:05, Chris Darroch wrote:
> > OK, I started working on this (skeleton of of the patch is ready), but
> > before I go any further, could you give me a hint on the semantics of
> > the above. What I'm not getting is APR_DBD_TRANS_COMMIT v.
> > APR_DBD_TRANS_COMMIT_ON_SUCCESS. Isn't that the same? I mean, you can't
> > forcefully commit anything - the database won't take it.
There's rather more than that: after any failed operation within
a transaction, apr_dbd assumes transaction failure and declines
to attempt any further ops, without reference to the backend.
Thus:
> > Or is there something I missed here...
>
> Well, this may not make sense, but what I was thinking was
> that most drivers currently seem to decide whether to rollback
> or commit based on whether some errors have occurred in other
> calls and an internal flag has been set. For example, from pgsql:
>
> if (trans->errnum) {
> trans->errnum = 0;
> res = PQexec(trans->handle->conn, "ROLLBACK");
> }
> else {
> res = PQexec(trans->handle->conn, "COMMIT");
> }
Indeedie.
> What I was thinking was that this is the COMMIT_ON_SUCCESS
> default logic. ROLLBACK obviously forces a rollback. COMMIT
> would attempt a DB commit regardless of whether the driver
> had flagged anything in previously calls. So, like this:
Bearing in mind the above, under what circumstances would
that be meaningful? It's predicated on an assumption that
we have recoverable errors within a transaction. But apr_dbd
doesn't support that (except insofar as a driver may correct
errors within its black box). Or am I missing something?
> switch (trans->mode) {
> case APR_DBD_TRANSACTION_COMMIT:
> res = PQexec(trans->handle->conn, "COMMIT");
> break;
The only usage case I can see where that would make sense is
immediately after an error return, to perform some error-correction
then commit. But any such error-correction would necessarily
take you outside the apr_dbd layer and into direct ops on the
native handle. So having apr_dbd support the commit seems
to have little point, AFAICS.
> 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;
> }
That's fine.
> That's just a quick sketch ... if that's dumb, by all means
> do something else! I should be able to focus on this a bit
> next week, as I said, if that helps any. Cheers,
I did express a preference before, but it's not a strong one.
I would also accept Bojan's original patch (simply add
apr_dbd_transaction_rollback to the API), or your scheme
outlined here if you can convince me force-commit has a role.
--
Nick Kew