mOptions = array(); } else { $this->mOptions = array( 'FOR UPDATE' ); } // @todo get connection only when it's needed? make sure that doesn't break anything, especially transactions! $this->mDb = wfGetDB( DB_MASTER ); $this->mWithTransaction = $withTransaction; $this->mHasTransaction = false; } /** * Begin a database transaction, if $withTransaction was given as true in the constructor for this SqlDataUpdate. * * Because nested transactions are not supported by the Database class, this implementation * checks Database::trxLevel() and only opens a transaction if none is already active. */ public function beginTransaction() { if ( !$this->mWithTransaction ) { return; } // NOTE: nested transactions are not supported, only start a transaction if none is open if ( $this->mDb->trxLevel() === 0 ) { $this->mDb->begin( get_class( $this ) . '::beginTransaction' ); $this->mHasTransaction = true; } } /** * Commit the database transaction started via beginTransaction (if any). */ public function commitTransaction() { if ( $this->mHasTransaction ) { $this->mDb->commit( get_class( $this ) . '::commitTransaction' ); $this->mHasTransaction = false; } } /** * Abort the database transaction started via beginTransaction (if any). */ public function abortTransaction() { if ( $this->mHasTransaction ) { //XXX: actually... maybe always? $this->mDb->rollback( get_class( $this ) . '::abortTransaction' ); $this->mHasTransaction = false; } } /** * Invalidate the cache of a list of pages from a single namespace. * This is intended for use by subclasses. * * @param $namespace Integer * @param $dbkeys Array */ protected function invalidatePages( $namespace, array $dbkeys ) { if ( $dbkeys === array() ) { return; } /** * Determine which pages need to be updated * This is necessary to prevent the job queue from smashing the DB with * large numbers of concurrent invalidations of the same page */ $now = $this->mDb->timestamp(); $ids = array(); $res = $this->mDb->select( 'page', array( 'page_id' ), array( 'page_namespace' => $namespace, 'page_title' => $dbkeys, 'page_touched < ' . $this->mDb->addQuotes( $now ) ), __METHOD__ ); foreach ( $res as $row ) { $ids[] = $row->page_id; } if ( $ids === array() ) { return; } /** * Do the update * We still need the page_touched condition, in case the row has changed since * the non-locking select above. */ $this->mDb->update( 'page', array( 'page_touched' => $now ), array( 'page_id' => $ids, 'page_touched < ' . $this->mDb->addQuotes( $now ) ), __METHOD__ ); } }