Re: [PATCH]: Introduce APR DBD transaction mode
Bojan Smojver wrote: Here is the patch along the lines of setting the modes of the transaction. It doesn't have force commit, but if the list decides that it's the right thing to do, I'll rework. I didn't test this - it's just a prototype. A patch for folks using MySQL is included as well. Looks pretty good to me. I think you're right that we only need commit and rollback as options for the end of a transaction, but for possibly surprising reason (see below) Nick Kew wrote: 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. I think perhaps we should remove this logic from all the drivers entirely. Here's why, and it connects back to my initial notion of a forceable commit option, which I realize now was really based on an instinct that I'd sometimes want to override the built-in decision by apr_dbd to cancel my transaction. A simple example from (my) real life would be that I sometimes want to insert a row and, if a constraint violation occurs, do something else. If I do that work outside an apr_dbd transaction, no problem. If I do it inside, though, apr_dbd will prevent me from proceeding once I get the constraint violation. Applications using apr_dbd without transactions already have to handle all the possible errors that they care about from the databases they're using. We don't, for example, have the apr_dbd drivers attempt to map all possible DB errors to a standard set of APR errors -- that would just be an impossible task, I think. So I'm inclined to say that when using transactions, things should be no different; apr_dbd should get out of the way and let the application decide which errors it can recover from. Here's another real-life example; this one is database-specific. I sometimes register application-defined error codes with Oracle and then set up triggers to throw those errors based on some PL/SQL logic. These are errors that are meaningful to my higher-level application and in some cases signal it to do something else; I don't really want apr_dbd deciding that one of these errors means the whole transaction is bad. Thoughts, flames? Chris. -- GPG Key ID: 366A375B GPG Key Fingerprint: 485E 5041 17E1 E2BB C263 E4DE C8E3 FA36 366A 375B
Re: [PATCH]: Introduce APR DBD transaction mode
On Monday 01 May 2006 16:47, Chris Darroch wrote: Nick Kew wrote: 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. I think perhaps we should remove this logic from all the drivers entirely. Here's why, and it connects back to my initial notion of a forceable commit option, which I realize now was really based on an instinct that I'd sometimes want to override the built-in decision by apr_dbd to cancel my transaction. Well, postgresql will give us essentially the same logic within its transactions, and I had an idea other databases did similar things. Cheaper for apr_dbd to do it without troubling the backend, and I'd be reluctant to change that, at least as default behaviour. A simple example from (my) real life would be that I sometimes want to insert a row and, if a constraint violation occurs, do something else. If I do that work outside an apr_dbd transaction, no problem. If I do it inside, though, apr_dbd will prevent me from proceeding once I get the constraint violation. OK, fairy nuff. Bojan's proposed patch (or some variant on it) will set transaction mode. How about if we add a further APR_DBD_TRANSACTION_CLEARERR flag (to be ORed with the mode) that'll let the application clear an error. Drivers could reset the application state and make any corresponding calls to the backend. Would you be happy with that? -- Nick Kew
Re: [PATCH]: Introduce APR DBD transaction mode
Nick: Bojan's proposed patch (or some variant on it) will set transaction mode. How about if we add a further APR_DBD_TRANSACTION_CLEARERR flag (to be ORed with the mode) that'll let the application clear an error. Drivers could reset the application state and make any corresponding calls to the backend. Would you be happy with that? Sounds good -- if you see an error you can handle, you clear the transaction's error state back to ok, and apr_dbd lets you proceed. Seems very reasonable to me; thanks! Chris. -- GPG Key ID: 366A375B GPG Key Fingerprint: 485E 5041 17E1 E2BB C263 E4DE C8E3 FA36 366A 375B
Re: [PATCH]: Introduce APR DBD transaction mode
On Mon, 2006-05-01 at 14:11 -0400, Chris Darroch wrote: Sounds good -- if you see an error you can handle, you clear the transaction's error state back to ok, and apr_dbd lets you proceed. Seems very reasonable to me; thanks! Perhaps. However, it would seem that not all databases behave the same on error mid-transaction. Compare SQLite3 with PostgreSQL: -- sqlite create table test (a text primary key); sqlite begin; sqlite insert into test values ('a'); sqlite insert into test values ('a'); SQL error: column a is not unique sqlite end; sqlite select * from test; a-- ONE ROW INSERTED! -- -- postgres=# create table test (a text primary key); NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index test_pkey for table test CREATE TABLE postgres=# begin; BEGIN postgres=# insert into test values ('a'); INSERT 0 1 postgres=# insert into test values ('a'); ERROR: duplicate key violates unique constraint test_pkey postgres=# end; ROLLBACK postgres=# select * from test; a --- (0 rows)-- NOTHING INSERTED! -- In other words, once PostgreSQL encounters an error mid-transaction, it would seem that one needs a savepoint to fix things before anything gets committed. Clearing APR DBD error, doesn't help with PostgreSQL - the transaction will still be rolled back by the database. MySQL 5 behaves like SQLite3. Not sure what Oracle does - I can check when I get to work later on (but I'm guessing it would be similar to PostgreSQL). Maybe there is a way to tell PostgreSQL not to fail - not sure... -- Bojan
Re: [PATCH]: Introduce APR DBD transaction mode
On Mon, 2006-05-01 at 12:41 -0700, Tyler MacDonald wrote: Maybe if MySQL is detected APR should refuse to support transactions and tell the end user to find a non-broken database engine. :-) He, he... Something like this: #define APR_EGOFINDOTHERDB 9 -- Bojan
Re: [PATCH]: Introduce APR DBD transaction mode
On Monday 01 May 2006 20:50, Bojan Smojver wrote: On Mon, 2006-05-01 at 12:41 -0700, Tyler MacDonald wrote: huh? Not in my mailbox, nor at marc.theaimsgroup.com ... Maybe if MySQL is detected APR should refuse to support transactions and tell the end user to find a non-broken database engine. :-) AIUI, MySQL transaction support depends on the mysql backend selected (bdb vs innodb vs ...). What sucks is that it just ignores you silently when you have a backend that doesn't support them. -- Nick Kew
Re: [PATCH]: Introduce APR DBD transaction mode
Nick Kew [EMAIL PROTECTED] wrote: On Monday 01 May 2006 20:50, Bojan Smojver wrote: On Mon, 2006-05-01 at 12:41 -0700, Tyler MacDonald wrote: huh? Not in my mailbox, nor at marc.theaimsgroup.com ... I'll forward it. I accidentally sent it from my work email [EMAIL PROTECTED] so it's being held for moderation... AIUI, MySQL transaction support depends on the mysql backend selected (bdb vs innodb vs ...). What sucks is that it just ignores you silently when you have a backend that doesn't support them. Yep. That's evil as well. :-) - Tyler
Fwd: Re: [PATCH]: Introduce APR DBD transaction mode
Here's the message that wsa sent from the wrong address: - Forwarded message from Tyler MacDonald [EMAIL PROTECTED] - From: Tyler MacDonald [EMAIL PROTECTED] To: Bojan Smojver [EMAIL PROTECTED] Cc: dev@apr.apache.org Subject: Re: [PATCH]: Introduce APR DBD transaction mode Bojan Smojver [EMAIL PROTECTED] wrote: Perhaps. However, it would seem that not all databases behave the same on error mid-transaction. Compare SQLite3 with PostgreSQL: SQLite3's transactions leave a bit to be desired.. and on that note, be very, very wary of MySQL as well. It allows a transaction to be committed even if there were errors during the transaction (pasted below), and it also will AUTOMATICALLY COMMIT A TRANSACTION IF YOU DO A CREATE TABLE. That part is EVIL, EVIL, EVIL!! (sorry, venting...) But yeah. Because of implicit commits in MySQL (see http://dev.mysql.com/doc/refman/5.1/en/implicit-commit.html), any sort of tracking of a transaction is pretty much moot under MySQL. This drove me mad when I was working on DBIx::Transaction (http://search.cpan.org/~CRAKRJACK/DBIx-Transaction-0.008) and DBIx::Migration::Directories (http://search.cpan.org/~CRAKRJACK/DBIx-Migration-Directories-0.05). Maybe if MySQL is detected APR should refuse to support transactions and tell the end user to find a non-broken database engine. :-) Cheers, Tyler mysql begin work; Query OK, 0 rows affected (0.00 sec) mysql insert into foo values (1); Query OK, 1 row affected (0.00 sec) mysql insert into foo values (1); Query OK, 1 row affected (0.00 sec) mysql invert into foo values (1); ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'invert into foo values (1)' at line 1 mysql commit; Query OK, 0 rows affected (0.01 sec) mysql select * from foo; +--+ | bar | +--+ | 1| | 1| +--+ 2 rows in set (0.00 sec) - End forwarded message -
Re: [PATCH]: Introduce APR DBD transaction mode
Bojan Smojver [EMAIL PROTECTED] wrote: Perhaps. However, it would seem that not all databases behave the same on error mid-transaction. Compare SQLite3 with PostgreSQL: SQLite3's transactions leave a bit to be desired.. and on that note, be very, very wary of MySQL as well. It allows a transaction to be committed even if there were errors during the transaction (pasted below), and it also will AUTOMATICALLY COMMIT A TRANSACTION IF YOU DO A CREATE TABLE. That part is EVIL, EVIL, EVIL!! (sorry, venting...) But yeah. Because of implicit commits in MySQL (see http://dev.mysql.com/doc/refman/5.1/en/implicit-commit.html), any sort of tracking of a transaction is pretty much moot under MySQL. This drove me mad when I was working on DBIx::Transaction (http://search.cpan.org/~CRAKRJACK/DBIx-Transaction-0.008) and DBIx::Migration::Directories (http://search.cpan.org/~CRAKRJACK/DBIx-Migration-Directories-0.05). Maybe if MySQL is detected APR should refuse to support transactions and tell the end user to find a non-broken database engine. :-) Cheers, Tyler mysql begin work; Query OK, 0 rows affected (0.00 sec) mysql insert into foo values (1); Query OK, 1 row affected (0.00 sec) mysql insert into foo values (1); Query OK, 1 row affected (0.00 sec) mysql invert into foo values (1); ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'invert into foo values (1)' at line 1 mysql commit; Query OK, 0 rows affected (0.01 sec) mysql select * from foo; +--+ | bar | +--+ | 1| | 1| +--+ 2 rows in set (0.00 sec)
Re: [PATCH]: Introduce APR DBD transaction mode
On Monday 01 May 2006 02:28, Bojan Smojver wrote: Here is the patch along the lines of setting the modes of the transaction. It doesn't have force commit, but if the list decides that it's the right thing to do, I'll rework. I didn't test this - it's just a prototype. A patch for folks using MySQL is included as well. OK, here's a sketch for the shape of an update based on this thread but without reference to TFM. Any advances on this for the underlying model? Or simplifications? (1) in apr_dbd.h #define APR_DBD_TRANSACTION_COMMIT 0x01 /* force */ #define APR_DBD_TRANSACTION_ROLLBACK 0x02 /* force */ #define APR_DBD_TRANSACTION_DEFAULT0x03 /* commit-unless-error */ #define APR_DBD_TRANSACTION_MODEBITS 0x03 #define APR_DBD_TRANSACTION_CLEARERR 0x04 (2) in a driver static int dbd_foo_transaction_mode(apr_dbd_transaction_t *trans, int flags) { int ret = 0 int mode = flags APR_DBD_TRANSACTION_MODEBITS; switch (flags) { case APR_DBD_TRANSACTION_COMMIT: case APR_DBD_TRANSACTION_ROLLBACK: trans-mode = mode; break; default: trans-mode = APR_DBD_TRANSACTION_DEFAULT ; break; } if ((trans-errnum != 0) (flags APR_DBD_TRANSACTION_CLEARERR)) { ret = foo_clearerror(...); if (ret == foo_success) { trans-errnum = 0; } } return ret; /* or juggle if foo_success != 0 */ } -- Nick Kew
Re: [PATCH]: Introduce APR DBD transaction mode
Quoting Bojan Smojver [EMAIL PROTECTED]: Not sure what Oracle does - I can check when I get to work later on (but I'm guessing it would be similar to PostgreSQL). Actually, Oracle will commit even if there were errors. So, the situation is that for PostgreSQL, resetting the transaction error code is meaningless - the whole transaction will be rolled back eventually, unless explicit savepoints are used. Other databases will happily ignore the errors and commit whatever remains. -- Bojan
Re: [PATCH]: Introduce APR DBD transaction mode
Quoting Nick Kew [EMAIL PROTECTED]: static int dbd_foo_transaction_mode(apr_dbd_transaction_t *trans, int flags) { int ret = 0 int mode = flags APR_DBD_TRANSACTION_MODEBITS; switch (flags) { ^ |--- should be mode? case APR_DBD_TRANSACTION_COMMIT: case APR_DBD_TRANSACTION_ROLLBACK: trans-mode = mode; break; default: trans-mode = APR_DBD_TRANSACTION_DEFAULT ; break; } if ((trans-errnum != 0) (flags APR_DBD_TRANSACTION_CLEARERR)) { ret = foo_clearerror(...); I'm guessing foo_clearerror() is a database specific function for clearing errors, if such a beast exists. If not, user gets back APR_ENOTIMPL status and the whole transaction must be rolled back. This would obviously need to be called every time an error code is returned by query/select, right? Still a little bit unclear on the function of APR_DBD_TRANSACTION_DEFAULT here. Given that the errors need to be cleared explicitly anyway (or at least that's how I read it), having one commit mode should be sufficient (i.e. if the errors weren't cleared by using APR_DBD_TRANSACTION_CLEARERR, commit won't work anyway). -- Bojan
Re: [PATCH]: Introduce APR DBD transaction mode
On Tuesday 02 May 2006 00:53, Bojan Smojver wrote: I'm guessing foo_clearerror() is a database specific function for clearing errors, if such a beast exists. Yep. If not, user gets back APR_ENOTIMPL status and the whole transaction must be rolled back. Erm, no. It it doesn't exist, that reduces to resetting trans-errnum. This would obviously need to be called every time an error code is returned by query/select, right? If the application wants to handle the error (other than in the default manner) then yes. Still a little bit unclear on the function of APR_DBD_TRANSACTION_DEFAULT here. Given that the errors need to be cleared explicitly anyway (or at least that's how I read it), having one commit mode should be sufficient (i.e. if the errors weren't cleared by using APR_DBD_TRANSACTION_CLEARERR, commit won't work anyway). Well, it's something we can initialise and reset to. It'll just give current behaviour. Could be relevant in cases like oracle, where (according to your earlier post) it will commit even when there's an error, so that gives us three behaviours that are clearly distinct. -- Nick Kew
Re: [PATCH]: Introduce APR DBD transaction mode
Quoting Nick Kew [EMAIL PROTECTED]: Erm, no. It it doesn't exist, that reduces to resetting trans-errnum. Ah, yes. Sorry. I meant we return APR_ENOTIMPL if the database cannot possibly support resetting of trans-errnum correctly (such as PGSQL). Otherwise, we just reset (i.e. SQLite, Oracle, MySQL). This would obviously need to be called every time an error code is returned by query/select, right? If the application wants to handle the error (other than in the default manner) then yes. Right. Well, it's something we can initialise and reset to. It'll just give current behaviour. Could be relevant in cases like oracle, where (according to your earlier post) it will commit even when there's an error, so that gives us three behaviours that are clearly distinct. Hmm, let's assume that apr_dbd_transaction_end in the underlying driver takes into account all three modes - it would still work only for the last query/select before the call to transaction end. All queries before that, for which reset was not executed, would not even touch the database (due to the trans-errnum check at the beginning of each function). So, reset needs to be called explicitly if something is to happen in query/select after a bad status code. Given that, it would be more uniform to ask callers to reset the error code explicitly, even for the last query/select before end, if they are convinced that this transaction should in fact be committed. And once they do that, one commit mode is quite sufficient. Something like this: Two explicit modes: #define APR_DBD_TRANSACTION_COMMIT 0 #define APR_DBD_TRANSACTION_ROLLBACK 1 For: apr_dbd_transaction_mode_get() apr_dbd_transaction_mode_set() And another functions call: apr_dbd_transaction_recover() The latter would attempt to recover the transaction from the error (if underlying database permits and it all works out). It would be used by caller if any of the query/select functions return bad status code and the caller is confident the transaction should proceed as normal. This function would look something like this in the driver: static int dbd_foo_transaction_recover(apr_dbd_transaction_t *trans) { int ret = -1; if (trans) { ret = foo_recover(...); if (ret == foo_success ) { trans-errnum = 0; } } return ret; } Databases that don't support such functionality (e.g. PostgreSQL) would simply return APR_ENOTIMPL. -- Bojan
Re: [PATCH]: Introduce APR DBD transaction mode
Quoting Bojan Smojver [EMAIL PROTECTED]: Databases that don't support such functionality (e.g. PostgreSQL) would simply return APR_ENOTIMPL. Actually, I take this bit back. We *always* reset trans-errnum, just like Nick said (even when there is no foo_clearerr()). And this to be able to execute ROLLBACK TO SAVEPOINT suchandsuch for a database like PGSQL, in order to actually fix the underlying database nastiness. -- Bojan
Re: [PATCH]: Introduce APR DBD transaction mode
Quoting Bojan Smojver [EMAIL PROTECTED]: Something like this: Attached example patches. -- Bojan Index: include/apr_dbd.h === --- include/apr_dbd.h (revision 398759) +++ include/apr_dbd.h (working copy) @@ -153,6 +153,38 @@ apr_pool_t *pool, apr_dbd_transaction_t *trans); +#define APR_DBD_TRANSACTION_COMMIT 0 /** commit the transaction */ +#define APR_DBD_TRANSACTION_ROLLBACK 1 /** rollback the transaction */ + +/** apr_dbd_transaction_mode_get: get the mode of transaction + * + * @param driver - the driver + * @param trans - the transaction + * @return mode of transaction + */ +APU_DECLARE(int) apr_dbd_transaction_mode_get(const apr_dbd_driver_t *driver, + apr_dbd_transaction_t *trans); + +/** apr_dbd_transaction_mode_set: set the mode of transaction + * + * @param driver - the driver + * @param trans - the transaction + * @param mode - new mode of the transaction + * @return new mode of transaction + */ +APU_DECLARE(int) apr_dbd_transaction_mode_set(const apr_dbd_driver_t *driver, + apr_dbd_transaction_t *trans, + int mode); + +/** apr_dbd_transaction_recover: recover transaction from an error condition + * + * @param driver - the driver + * @param trans - the transaction + * @return 0 for success or error code + */ +APU_DECLARE(int) apr_dbd_transaction_recover(const apr_dbd_driver_t *driver, + apr_dbd_transaction_t *trans); + /** apr_dbd_query: execute an SQL query that doesn't return a result set * * @param driver - the driver Index: include/private/apr_dbd_internal.h === --- include/private/apr_dbd_internal.h (revision 398759) +++ include/private/apr_dbd_internal.h (working copy) @@ -82,9 +82,9 @@ /** transaction: start a transaction. May be a no-op. * - * @param pool - a pool to use for error messages (if any). + * @param pool - a pool to use for error messages (if any). * @param handle - the connection - * @param transaction - ptr to a transaction. May be null on entry + * @param trans - ptr to a transaction. May be null on entry * @return 0 for success or error code */ int (*start_transaction)(apr_pool_t *pool, apr_dbd_t *handle, @@ -94,7 +94,7 @@ * (commit on success, rollback on error). * May be a no-op. * - * @param transaction - the transaction. + * @param trans - the transaction. * @return 0 for success or error code */ int (*end_transaction)(apr_dbd_transaction_t *trans); @@ -254,6 +254,28 @@ * @return param name, or NULL if col is out of bounds. */ const char* (*get_name)(const apr_dbd_results_t *res, int col); + +/** transaction_mode_get: get the mode of transaction + * + * @param trans - the transaction. + * @return mode of transaction + */ +int (*transaction_mode_get)(apr_dbd_transaction_t *trans); + +/** transaction_mode_set: get the mode of transaction + * + * @param trans - the transaction. + * @param mode - new mode of the transaction + * @return new mode of transaction + */ +int (*transaction_mode_set)(apr_dbd_transaction_t *trans, int mode); + +/** transaction_recover: recover transaction from an error condition + * + * @param trans - the transaction. + * @return 0 for success or error code + */ +int (*transaction_recover)(apr_dbd_transaction_t *trans); }; /* Export mutex lock/unlock for drivers that need it */ Index: dbd/apr_dbd_sqlite2.c === --- dbd/apr_dbd_sqlite2.c (revision 398759) +++ dbd/apr_dbd_sqlite2.c (working copy) @@ -29,6 +29,7 @@ #include apr_dbd_internal.h struct apr_dbd_transaction_t { +int mode; int errnum; apr_dbd_t *handle; }; @@ -292,7 +293,8 @@ int ret = -1; /* no transaction is an error cond */ if (trans) { -if (trans-errnum) { +/* rollback on error or explicit rollback request */ +if (trans-errnum || trans-mode) { trans-errnum = 0; ret = dbd_sqlite_query(trans-handle, rows, @@ -308,6 +310,36 @@ return ret; } +static int dbd_sqlite_transaction_mode_get(apr_dbd_transaction_t *trans) +{ +if (!trans) +return APR_DBD_TRANSACTION_COMMIT; + +return trans-mode; +} + +static int dbd_sqlite_transaction_mode_set(apr_dbd_transaction_t *trans, + int mode) +{ +if (!trans) +return APR_DBD_TRANSACTION_COMMIT; + +return trans-mode = (mode ? APR_DBD_TRANSACTION_ROLLBACK +
[PATCH]: Introduce APR DBD transaction mode
Here is the patch along the lines of setting the modes of the transaction. It doesn't have force commit, but if the list decides that it's the right thing to do, I'll rework. I didn't test this - it's just a prototype. A patch for folks using MySQL is included as well. -- Bojan Index: include/apr_dbd.h === --- include/apr_dbd.h (revision 398484) +++ include/apr_dbd.h (working copy) @@ -153,6 +153,29 @@ apr_pool_t *pool, apr_dbd_transaction_t *trans); +#define APR_DBD_TRANSACTION_COMMIT 0 /** commit the transaction */ +#define APR_DBD_TRANSACTION_ROLLBACK 1 /** rollback the transaction */ + +/** apr_dbd_transaction_mode_get: get the mode of transaction + * + * @param driver - the driver + * @param trans - the transaction + * @return mode of transaction + */ +APU_DECLARE(int) apr_dbd_transaction_mode_get(const apr_dbd_driver_t *driver, + apr_dbd_transaction_t *trans); + +/** apr_dbd_transaction_mode_set: set the mode of transaction + * + * @param driver - the driver + * @param trans - the transaction + * @param mode - new mode of the transaction + * @return new mode of transaction + */ +APU_DECLARE(int) apr_dbd_transaction_mode_set(const apr_dbd_driver_t *driver, + apr_dbd_transaction_t *trans, + int mode); + /** apr_dbd_query: execute an SQL query that doesn't return a result set * * @param driver - the driver Index: include/private/apr_dbd_internal.h === --- include/private/apr_dbd_internal.h (revision 398484) +++ include/private/apr_dbd_internal.h (working copy) @@ -82,9 +82,9 @@ /** transaction: start a transaction. May be a no-op. * - * @param pool - a pool to use for error messages (if any). + * @param pool - a pool to use for error messages (if any). * @param handle - the connection - * @param transaction - ptr to a transaction. May be null on entry + * @param trans - ptr to a transaction. May be null on entry * @return 0 for success or error code */ int (*start_transaction)(apr_pool_t *pool, apr_dbd_t *handle, @@ -94,7 +94,7 @@ * (commit on success, rollback on error). * May be a no-op. * - * @param transaction - the transaction. + * @param trans - the transaction. * @return 0 for success or error code */ int (*end_transaction)(apr_dbd_transaction_t *trans); @@ -254,6 +254,21 @@ * @return param name, or NULL if col is out of bounds. */ const char* (*get_name)(const apr_dbd_results_t *res, int col); + +/** transaction_mode_get: get the mode of transaction + * + * @param trans - the transaction. + * @return mode of transaction + */ +int (*transaction_mode_get)(apr_dbd_transaction_t *trans); + +/** transaction_mode_set: get the mode of transaction + * + * @param trans - the transaction. + * @param mode - new mode of the transaction + * @return new mode of transaction + */ +int (*transaction_mode_set)(apr_dbd_transaction_t *trans, int mode); }; /* Export mutex lock/unlock for drivers that need it */ Index: dbd/apr_dbd_sqlite2.c === --- dbd/apr_dbd_sqlite2.c (revision 398484) +++ dbd/apr_dbd_sqlite2.c (working copy) @@ -29,6 +29,7 @@ #include apr_dbd_internal.h struct apr_dbd_transaction_t { +int mode; int errnum; apr_dbd_t *handle; }; @@ -292,7 +293,8 @@ int ret = -1; /* no transaction is an error cond */ if (trans) { -if (trans-errnum) { +/* rollback on error or explicit rollback request */ +if (trans-errnum || trans-mode) { trans-errnum = 0; ret = dbd_sqlite_query(trans-handle, rows, @@ -308,6 +310,18 @@ return ret; } +static int dbd_sqlite_transaction_mode_get(apr_dbd_transaction_t *trans) +{ +return trans-mode; +} + +static int dbd_sqlite_transaction_mode_set(apr_dbd_transaction_t *trans, + int mode) +{ +return trans-mode = (mode ? APR_DBD_TRANSACTION_ROLLBACK + : APR_DBD_TRANSACTION_COMMIT); +} + static apr_dbd_t *dbd_sqlite_open(apr_pool_t * pool, const char *params_) { apr_dbd_t *sql; @@ -396,6 +410,8 @@ dbd_sqlite_pvselect, dbd_sqlite_pquery, dbd_sqlite_pselect, -dbd_sqlite_get_name +dbd_sqlite_get_name, +dbd_sqlite_transaction_mode_get, +dbd_sqlite_transaction_mode_set }; #endif Index: dbd/apr_dbd_sqlite3.c === --- dbd/apr_dbd_sqlite3.c (revision 398484) +++
Re: [PATCH]: Introduce APR DBD transaction mode
Quoting Bojan Smojver [EMAIL PROTECTED]: A patch for folks using MySQL is included as well. Sorry about the traling comma after dbd_mysql_transaction_mode_set - lazy cut/paste :-( -- Bojan