beginTransaction(); $open_transactions[] = $update; } // do work foreach ( $updates as $update ) { $update->doUpdate(); } // commit transactions while ( count( $open_transactions ) > 0 ) { $trans = array_pop( $open_transactions ); $trans->commitTransaction(); } } catch ( Exception $ex ) { $exception = $ex; wfDebug( "Caught exception, will rethrow after rollback: " . $ex->getMessage() . "\n" ); } // rollback remaining transactions while ( count( $open_transactions ) > 0 ) { $trans = array_pop( $open_transactions ); $trans->rollbackTransaction(); } if ( $exception ) { throw $exception; // rethrow after cleanup } } /** * Enqueue jobs for every DataUpdate that support enqueueUpdate() * and return the remaining DataUpdate objects (those that do not) * * @param DataUpdate[] $updates A list of DataUpdate instances * @return DataUpdate[] * @since 1.27 */ protected static function enqueueUpdates( array $updates ) { $remaining = array(); foreach ( $updates as $update ) { if ( $update instanceof EnqueueableDataUpdate ) { $spec = $update->getAsJobSpecification(); JobQueueGroup::singleton( $spec['wiki'] )->push( $spec['job'] ); } else { $remaining[] = $update; } } return $remaining; } } /** * Interface that marks a DataUpdate as enqueuable via the JobQueue * * Such updates must be representable using IJobSpecification, so that * they can be serialized into jobs and enqueued for later execution * * @since 1.27 */ interface EnqueueableDataUpdate { /** * @return array (wiki => wiki ID, job => IJobSpecification) */ public function getAsJobSpecification(); }