Return-Path: Delivered-To: apmail-apr-dev-archive@www.apache.org Received: (qmail 27312 invoked from network); 2 May 2006 04:46:03 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 2 May 2006 04:46:03 -0000 Received: (qmail 3688 invoked by uid 500); 2 May 2006 04:46:02 -0000 Delivered-To: apmail-apr-dev-archive@apr.apache.org Received: (qmail 3643 invoked by uid 500); 2 May 2006 04:46:01 -0000 Mailing-List: contact dev-help@apr.apache.org; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Id: Delivered-To: mailing list dev@apr.apache.org Received: (qmail 3625 invoked by uid 99); 2 May 2006 04:46:01 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 01 May 2006 21:46:01 -0700 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_HELO_PASS,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (asf.osuosl.org: domain of bojan@rexursive.com designates 203.171.74.242 as permitted sender) Received: from [203.171.74.242] (HELO beauty.rexursive.com) (203.171.74.242) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 01 May 2006 21:46:00 -0700 Received: by beauty.rexursive.com (Postfix, from userid 48) id 529F0256C84; Tue, 2 May 2006 14:45:38 +1000 (EST) Received: from cache4.syd.ops.aspac.uu.net (cache4.syd.ops.aspac.uu.net [203.166.96.238]) by www.rexursive.com (Horde MIME library) with HTTP; Tue, 02 May 2006 14:45:38 +1000 Message-ID: <20060502144538.gi44ih28j4sk4w0g@www.rexursive.com> Date: Tue, 02 May 2006 14:45:38 +1000 From: Bojan Smojver To: APR Development List Subject: Transaction modes, explicit rollbacks etc. MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; DelSp="Yes"; format="flowed" Content-Disposition: inline Content-Transfer-Encoding: quoted-printable User-Agent: Internet Messaging Program (IMP) H3 (4.1.1) X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N So, we know by now that some databases will fail the whole transaction =20 if any kind of error occurs, while some others won't. We also know =20 that sometimes one option is the desired behaviour, while at other =20 times the other option is what the caller wants - regardless of the =20 underlying database. So, given that APR DBD is supposed to be database =20 neutral, here is another solution for the same problem. #define APR_DBD_TRANSACTION_COMMIT 0x00 /**< commit the transaction *= / #define APR_DBD_TRANSACTION_ROLLBACK 0x01 /**< rollback the =20 transaction */ #define APR_DBD_TRANSACTION_IGNORE_ERRORS 0x02 /**< ignore error conditions = */ We then have our already known functions: apr_dbd_transaction_mode_get() apr_dbd_transaction_mode_set() So, we can call (once only!): apr_dbd_transaction_mode_set(driver, trans, APR_DBD_TRANSACTION_COMMIT| APR_DBD_TRANSACTION_IGNORE_ERRORS); Then, inside the query/select functions we leave trans->errnum at zero =20 in case any error occurs, but return the status to the caller. If the =20 caller is intersted in the status, he/she can do something about it =20 (such as call mode set with ROLLBACK and then call end, to rollback). =20 Or, the caller can just continue with the next query/select. With =20 IGNORE_ERRORS set, at no point will the transaction be in a bad state =20 (i.e. this is how SQLite/Oracle/MySQL work). After all that, COMMIT is =20 executed and whatever is good gets committed (so this is effectively =20 COMMIT_ON_SUCCESS, but without the need to keep "recovering" the error =20 status). In case the IGNORE_ERRORS flag isn't set, the logic reverts to the =20 current behaviour (i.e. the way PGSQL does things). Any error triggers =20 a transaction error and the whole transaction will be rolled back for =20 sure. Here is the part we can now do with IGNORE_ERRORS that we could not do =20 before - we can make PGSQL behave like other databases if we so wish. =20 By setting IGNORE_ERRORS, we can insert SAVEPOINTS before every =20 query/select inside PGSQL driver automatically (i.e. the caller =20 doesn't have to do it). If an error occurs withing query/select, we =20 simply roll back to the previous savepoint, keep trans->errnum always =20 at zero and return the error code of the actual query. The caller can =20 then decide what should be done with the whole thing. This brings us =20 in line with transactional behaviour other databases. In summary, we can pick the behaviour we want and users get =20 savepoints/error recovery for free with PGSQL if they so wish. Let me know what you think... --=20 Bojan