Jut a small comment, if you do go ahead with the flag and not add a rollback funciton (which I think is much cleaner) then please be aware that the caller will need to know if the result was successful commit, successful rollback, or some other failure.

Chris Darroch wrote:

Bojan:

Nice. Do you want me to do a prototype patch or do you have something
already?

  Thanks!  Alas, I have nada in the way of an implementation; I'm
still trying to finish up my scoreboard/slow child_init/etc. fixes
for httpd.  I've also been away from the keyboard much of the previous
week; next week should be different, though, so I may have some
time to share/spare.

#define APR_DBD_TRANS_COMMIT_ON_SUCCESS 0
#define APR_DBD_TRANS_COMMIT            1
#define APR_DBD_TRANS_ROLLBACK          2
#define APR_DBD_TRANS_DEFAULT           APR_DBD_TRANS_COMMIT_ON_SUCCESS

  It occurs to me now that these should perhaps be yet more
verbose, e.g., APR_DBD_TRANSACTION_COMMIT, etc. to match
apr_dbd_transaction_start/end().

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.

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");
       }

  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:

   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;
   }

  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,

Chris.


Reply via email to