Last modified: 2010-05-15 16:03:49 UTC
When using the api to edit a page, most data is saved, such as, the page content, recentchanges, etc. Although, there is a lot that does not get updated in some cases. Notably, everything that happens in the LinksUpdate object. If I send an edit to the api that contains wikitext like categories, external links, images, etc, they will not be updated in the various db tables. The reason is, a new transaction begins just before the database insert and update statements for these things happens, and there is never a commit sent to the db. Essentially, the transaction is never committed, so these insert and update queries get rolled back in mysql. Having fully debugged the issue I've found the cause to be a small difference between regular mediawiki vs the api. If you'll notice in the main index.php for mediawiki one of the last lines of code is: $mediaWiki->finalCleanup ( $wgDeferredUpdateList, $wgOut ); That method runs a commit against the database, ensuring these types of issues don't pop up. That's fine I guess, but there is no equivalent in the api, hence this bug report. Although mostly a hack, I've resolved this issue by adding: $dbw = wfGetDB( DB_MASTER ); $dbw->commit(); to /includes/api/ApiEditPage.php just below line 193 from svn revision 32595 of the vodaphone branch. That is obviously not a long term solution, but it proves the problem is identified (not to mention I got to the point where I was outputting all queries run inside mediawiki, and a final commit was missing).
The proper way is doing $dbw->immediateCommit(); instead of $dbw->commit(); Don't ask me why. The long term solution is probably to have a finalCleanup(); method available for all write APIs.
I simply forgot to do $dbw->commit(); after performing the edit. Other write modules also do that. commit() was added in r32701, please test whether that fixes it.
Using r32701 it works :) Maybe you should talk to Bryan though, cause he is suggesting immediateCommit()
(In reply to comment #3) > Using r32701 it works :) Maybe you should talk to Bryan though, cause he is > suggesting immediateCommit() > Well that's what <http://www.mediawiki.org/wiki/Manual:Database_access#Lock_contention> tells me: "There are functions called begin() and commit() but they don't do what you would expect. Don't use them." In any case, the main code in Wiki.php is: function finalCleanup ( &$deferredUpdates, &$output ) { wfProfileIn( __METHOD__ ); $this->doUpdates( $deferredUpdates ); $this->doJobs(); # Now commit any transactions, so that unreported errors after output() don't roll back the whole thing $factory = wfGetLBFactory(); $factory->shutdown(); $output->output(); wfProfileOut( __METHOD__ ); } I think that wfGetLBFactory()->shutdown(); is the more appropriate way to do this?
(In reply to comment #4) > In any case, the main code in Wiki.php is: > > function finalCleanup ( &$deferredUpdates, &$output ) { > wfProfileIn( __METHOD__ ); > $this->doUpdates( $deferredUpdates ); > $this->doJobs(); > # Now commit any transactions, so that unreported errors after output() > don't roll back the whole thing > $factory = wfGetLBFactory(); > $factory->shutdown(); > $output->output(); > wfProfileOut( __METHOD__ ); > } > > I think that wfGetLBFactory()->shutdown(); is the more appropriate way to do > this? I'll just make sure API requests call MediaWiki::finalCleanup() when they finish and call $wgOut->disable() first so $output->output() becomes a no-op. That's probably cleaner than all those $dbw->begin() and $dbw->commit() calls.
(In reply to comment #5) > I'll just make sure API requests call MediaWiki::finalCleanup() when they > finish and call $wgOut->disable() first so $output->output() becomes a no-op. > That's probably cleaner than all those $dbw->begin() and $dbw->commit() calls. > I've done it slightly differently: I just had api.php call MediaWiki::doUpdates() when it finishes in r32717. I've also removed the commit() call in action=edit, haven't tested for other modules yet (haven't designed test interfaces for them yet).
Forgot to close this one