- $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
- $lb = ( $this->cluster !== false )
- ? $lbFactory->getExternalLB( $this->cluster )
- : $lbFactory->getMainLB( $this->domain );
-
- return ( $lb->getServerType( $lb->getWriterIndex() ) !== 'sqlite' )
- // Keep a separate connection to avoid contention and deadlocks;
- // However, SQLite has the opposite behavior due to DB-level locking.
- ? $lb->getConnectionRef( $index, [], $this->domain, $lb::CONN_TRX_AUTOCOMMIT )
- // Jobs insertion will be defered until the PRESEND stage to reduce contention.
- : $lb->getConnectionRef( $index, [], $this->domain );
+ if ( $this->server ) {
+ if ( $this->conn instanceof IDatabase ) {
+ return $this->conn;
+ } elseif ( $this->conn instanceof DBError ) {
+ throw $this->conn;
+ }
+
+ try {
+ $this->conn = Database::factory( $this->server['type'], $this->server );
+ } catch ( DBError $e ) {
+ $this->conn = $e;
+ throw $e;
+ }
+
+ return $this->conn;
+ } else {
+ $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+ $lb = is_string( $this->cluster )
+ ? $lbFactory->getExternalLB( $this->cluster )
+ : $lbFactory->getMainLB( $this->domain );
+
+ return ( $lb->getServerType( $lb->getWriterIndex() ) !== 'sqlite' )
+ // Keep a separate connection to avoid contention and deadlocks;
+ // However, SQLite has the opposite behavior due to DB-level locking.
+ ? $lb->getConnectionRef( $index, [], $this->domain, $lb::CONN_TRX_AUTOCOMMIT )
+ // Jobs insertion will be defered until the PRESEND stage to reduce contention.
+ : $lb->getConnectionRef( $index, [], $this->domain );
+ }
+ }
+
+ /**
+ * @param IDatabase $db
+ * @return ScopedCallback
+ */
+ private function getScopedNoTrxFlag( IDatabase $db ) {
+ $autoTrx = $db->getFlag( DBO_TRX ); // get current setting
+ $db->clearFlag( DBO_TRX ); // make each query its own transaction
+
+ return new ScopedCallback( function () use ( $db, $autoTrx ) {
+ if ( $autoTrx ) {
+ $db->setFlag( DBO_TRX ); // restore old setting
+ }
+ } );