*
* This is meant for multi-wiki systems that may share files.
*
- * All lock requests for a resource, identified by a hash string, will map
- * to one bucket. Each bucket maps to one or several peer DBs, each on their
- * own server, all having the filelocks.sql tables (with row-level locking).
+ * All lock requests for a resource, identified by a hash string, will map to one bucket.
+ * Each bucket maps to one or several peer DBs, each on their own server.
* A majority of peer DBs must agree for a lock to be acquired.
*
* Caching is used to avoid hitting servers that are down.
* @since 1.19
*/
abstract class DBLockManager extends QuorumLockManager {
- /** @var array Map of DB names to server config */
+ /** @var array[] Map of DB names to server config */
protected $dbServers; // (DB name => server config array)
/** @var BagOStuff */
protected $statusCache;
protected $safeDelay; // integer number of seconds
protected $session = 0; // random integer
- /** @var array Map Database connections (DB name => Database) */
+ /** @var IDatabase[] Map Database connections (DB name => Database) */
protected $conns = [];
/**
return $status;
}
+ abstract protected function doGetLocksOnServer( $lockSrv, array $paths, $type );
+
protected function freeLocksOnServer( $lockSrv, array $pathsByType ) {
return Status::newGood();
}
if ( !isset( $this->conns[$lockDb] ) ) {
$db = null;
if ( $lockDb === 'localDBMaster' ) {
- $lb = wfGetLBFactory()->getMainLB( $this->domain );
- $db = $lb->getConnection( DB_MASTER, [], $this->domain );
+ $db = $this->getLocalLB()->getConnection( DB_MASTER, [], $this->domain );
} elseif ( isset( $this->dbServers[$lockDb] ) ) {
$config = $this->dbServers[$lockDb];
$db = DatabaseBase::factory( $config['type'], $config );
return $this->conns[$lockDb];
}
+ /**
+ * @return LoadBalancer
+ */
+ protected function getLocalLB() {
+ return wfGetLBFactory()->getMainLB( $this->domain );
+ }
+
/**
* Do additional initialization for new lock DB connection
*
/**
* MySQL version of DBLockManager that supports shared locks.
+ *
+ * All lock servers must have the innodb table defined in locking/filelocks.sql.
* All locks are non-blocking, which avoids deadlocks.
*
* @ingroup LockManager
self::LOCK_EX => self::LOCK_EX
];
- /**
- * @param string $lockDb
- * @param IDatabase $db
- */
+ protected function getLocalLB() {
+ // Use a separate connection so releaseAllLocks() doesn't rollback the main trx
+ return wfGetLBFactory()->newMainLB( $this->domain );
+ }
+
protected function initConnection( $lockDb, IDatabase $db ) {
# Let this transaction see lock rows from other transactions
$db->query( "SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;" );