Transactions!

Max Kanat-Alexander mkanat at bugzilla.org
Thu Mar 15 04:46:16 UTC 2007


	I just checked in full transaction support in the database
layer, for Bugzilla.

	For anybody who doesn't know, a transaction is a way of doing a
bunch of SQL commands, and only writing to the disk once they've all
succeeded.

	Also, with transactions you get the same benefits of locking
without having to lock the whole table.

	Let me explain that last part (about getting the advantages of
locking) a bit more. When you do a transaction, this is what happens:

	1) You start the transaction. ($dbh->bz_start_transaction())

	2) You run at least one SQL statement.

	3) From that point on, every other statement sees the database
as it was immediately before you ran that first SQL statement. That is,
if the database gets modified somehow while you're in the middle of
your transaction, it won't affect your transaction. This is a Good
Thing, because it avoids race conditions. That's why we have locks in
the first place, for the most part--to avoid race conditions. (For
those who know about transactions, we use REPEATABLE READ. That could
always change, though, if we decide READ COMMITTED or SERIALIZABLE are
more appropriate.)

	4) You commit the transaction. ($dbh->bz_commit_transaction())

	5) The database writes your changes to disk.

	Instead of committing, you can also rollback the transaction,
which means that none of your changes will be written to disk. Only
ThrowError and Bugzilla::_cleanup() need to do this, really.

	Don't depend on rollback() for the correctness of your code.
It's there to handle critical cases, not to undo things that the code
decides it shouldn't have done. In other words, don't use rollback in
your code. (It should only be in the places where it is now.)

	You can see the POD docs for the transaction methods here:

	http://www.bugzilla.org/docs/tip/html/api/Bugzilla/DB.html#Transaction_Methods

	Note that you can call bz_start_transaction several times and
"nest" transactions (but read the docs there on how it works).

	Generally, we'll be replacing every bz_lock_tables call with a
call to bz_start_transaction.

	Under MySQL, however, the longdescs table isn't transactional.
That is, every write to it happens immediately. So it still needs to be
locked.

	If anybody has any questions about transactions, feel free to
ask here or in #mozwebtools.

	I'll probably be doing most of the conversions from
bz_lock_tables to bz_start_transaction myself, but if somebody wants to
help, they're welcome to file bugs and write patches. The tracking bug
is:

	https://bugzilla.mozilla.org/show_bug.cgi?id=121069

	-Max



More information about the developers mailing list