diff options
Diffstat (limited to 'includes/block/DatabaseBlockStore.php')
-rw-r--r-- | includes/block/DatabaseBlockStore.php | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/includes/block/DatabaseBlockStore.php b/includes/block/DatabaseBlockStore.php index c33157b58157..20f662e044d5 100644 --- a/includes/block/DatabaseBlockStore.php +++ b/includes/block/DatabaseBlockStore.php @@ -1044,6 +1044,7 @@ class DatabaseBlockStore { $targetUserName = (string)$target; $targetUserId = $target->getUserIdentity()->getId( $this->wikiId ); $targetConds = [ 'bt_user' => $targetUserId ]; + $targetLockKey = $dbw->getDomainID() . ':block:u:' . $targetUserId; } else { $targetAddress = (string)$target; $targetUserName = null; @@ -1052,6 +1053,8 @@ class DatabaseBlockStore { 'bt_address' => $targetAddress, 'bt_auto' => $isAuto, ]; + $targetLockKey = $dbw->getDomainID() . ':block:' . + ( $isAuto ? 'a' : 'i' ) . ':' . $targetAddress; } $condsWithCount = $targetConds; @@ -1059,6 +1062,15 @@ class DatabaseBlockStore { $condsWithCount['bt_count'] = $expectedTargetCount; } + $dbw->lock( $targetLockKey, __METHOD__ ); + $func = __METHOD__; + $dbw->onTransactionCommitOrIdle( + static function () use ( $dbw, $targetLockKey, $func ) { + $dbw->unlock( $targetLockKey, "$func.closure" ); + }, + __METHOD__ + ); + // This query locks the index gap when the target doesn't exist yet, // so there is a risk of throttling adjacent block insertions, // especially on small wikis which have larger gaps. If this proves to @@ -1076,6 +1088,7 @@ class DatabaseBlockStore { ->select( [ 'bt_id', 'bt_count' ] ) ->from( 'block_target' ) ->where( $targetConds ) + ->forUpdate() ->caller( __METHOD__ ) ->fetchResultSet(); if ( $res->numRows() > 1 ) { |