On 24.08.2012 18:55, Tyler Romeo wrote:
So, how would
you solve the use case I described? What I need to do is to
perform some checks before calling WikiPage::doEdit, and make sure the
result of
the check is still valid when the actual save
occurs.
SAVEPOINTs are basically nested transactions.
Yes. I'd like to use them.
MediaWiki's current behaviour is calling begin() when a transaction is open
silently commits the old transaction and starts a new one.
This SUCKS.
Can you describe the use case
in more detail?
So, in wikidata, we have global constraints, e.g. the requirement that only one
data item can have a sitelink to a given wikipedage (there's a 1:1 relationship
between wikipedia pages and data items). Before saving the item page, this
constraint needs to be checked, just before calling WikiPage::doEdit(). And we
also want to check for edit conflicts (comparing the base revision - note that
we are not using EditPage).
Anyway, wee need to do some checks before we call WikiPage::doEdit. And make
sure the database doesn't change before the actual save is done. So our checks
should be in the same transaction as the actual save.
But WikiPage::doEdit already opens a transaction. So we can no open a
surrounding transactiopn bracket - because nested transactions are not supported.
This could be solved be the "counting" or the "safepoint" solution,
the latter
being somewhat nicer. But we need to st least *one* of them, as far as I can tell.
The current situation is that code always has to know whether it is safe to call
some function X from inside a transaction, and conversely, any function needs to
decide on whether it expects to be called from within an existing transaction,
or if it should open its own.
These things can often not really be known in advance. This has caused trouble
in the past (caused by transactions being committed prematurely, because another
transaction started). I'm sure it will cause more pain in the future.
So I'm proposing to implement support for nested transactions, either by just
counting (and, on rollback, roll back all open transactions). Or by using
savepoints.
-- daniel