27 parent::__construct( $config );
29 $this->session = substr( $this->session, 0, 31 );
33 # Let this transaction see lock rows from other transactions
34 $db->
query(
"SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;", __METHOD__ );
35 # Do everything in a transaction as it all gets rolled back eventually
50 $status = StatusValue::newGood();
57 # Build up values for INSERT clause
58 foreach ( $paths as
$path ) {
62 if ( !isset( $this->locksHeld[
$path][self::LOCK_EX] ) ) {
63 $checkEXKeys[] = $key;
67 # Block new writers (both EX and SH locks leave entries here)...
68 $db->insert(
'filelocks_shared', $data, __METHOD__, [
'IGNORE' ] );
69 # Actually do the locking queries...
70 if (
$type == self::LOCK_SH ) {
71 # Bail if there are any existing writers...
72 if ( count( $checkEXKeys ) ) {
73 $blocked = $db->selectField(
74 'filelocks_exclusive',
76 [
'fle_key' => $checkEXKeys ],
82 # Other prospective writers that haven't yet updated filelocks_exclusive
83 # will recheck filelocks_shared after doing so and bail due to this entry.
85 $encSession = $db->addQuotes( $this->session );
86 # Bail if there are any existing writers...
87 # This may detect readers, but the safe check for them is below.
88 # Note: if two writers come at the same time, both bail :)
89 $blocked = $db->selectField(
92 [
'fls_key' =>
$keys,
"fls_session != $encSession" ],
96 # Build up values for INSERT clause
98 foreach (
$keys as $key ) {
99 $data[] = [
'fle_key' => $key ];
101 # Block new readers/writers...
102 $db->insert(
'filelocks_exclusive', $data, __METHOD__ );
103 # Bail if there are any existing readers...
104 $blocked = $db->selectField(
107 [
'fls_key' =>
$keys,
"fls_session != $encSession" ],
114 foreach ( $paths as
$path ) {
115 $status->fatal(
'lockmanager-fail-acquirelock',
$path );
127 $status = StatusValue::newGood();
129 foreach ( $this->conns as $lockDb => $db ) {
130 if ( $db->trxLevel() ) {
132 $db->rollback( __METHOD__ );
134 $status->fatal(
'lockmanager-fail-db-release', $lockDb );
Version of LockManager based on using named/row DB locks.
getConnection( $lockDb)
Get (or reuse) a connection to a lock DB.
string $session
Random 32-char hex number.
const LOCK_SH
Lock types; stronger locks have higher values.
sha1Base36Absolute( $path)
Get the base 36 SHA-1 of a string, padded to 31 digits.
MySQL version of DBLockManager that supports shared locks.
array $lockTypeMap
Mapping of lock types to the type actually used.
initConnection( $lockDb, IDatabase $db)
Do additional initialization for new lock DB connection Stable to override.
__construct(array $config)
Construct a new instance from configuration.
doGetLocksOnServer( $lockSrv, array $paths, $type)
Get a connection to a lock DB and acquire locks on $paths.