Skip to content

Commit cda417a

Browse files
committed
Move lock state into key from store
1 parent 2def8dd commit cda417a

File tree

2 files changed

+44
-16
lines changed

2 files changed

+44
-16
lines changed

src/Symfony/Component/Lock/Store/MysqlStore.php

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,6 @@ class MysqlStore implements PersistingStoreInterface
3131

3232
private int $connectionId;
3333

34-
/** @var bool[] */
35-
private static array $locksAcquired = [];
36-
3734
public function __construct(\PDO|string $connOrDsn, array $options = [])
3835
{
3936
if ($connOrDsn instanceof \PDO) {
@@ -51,20 +48,20 @@ public function __construct(\PDO|string $connOrDsn, array $options = [])
5148

5249
public function save(Key $key): void
5350
{
54-
$id = $this->getLockId($key);
55-
56-
if (self::$locksAcquired[$id] ?? false) {
51+
$stateKey = $this->getStateKey($key);
52+
if ($key->hasState($stateKey)) {
5753
return;
5854
}
5955

56+
$name = self::getLockName($key);
6057
$stmt = $this->conn->prepare('SELECT IF(IS_USED_LOCK(:name) = CONNECTION_ID(), -1, GET_LOCK(:name, 0))');
61-
$stmt->bindValue(':name', self::getLockName($key), \PDO::PARAM_STR);
58+
$stmt->bindValue(':name', $name, \PDO::PARAM_STR);
6259
$stmt->execute();
6360
$result = $stmt->fetchColumn();
6461

6562
// lock acquired
6663
if (1 === $result) {
67-
self::$locksAcquired[$id] = true;
64+
$key->setState($stateKey, $name);
6865

6966
return;
7067
}
@@ -91,12 +88,12 @@ public function delete(Key $key): void
9188
$stmt->bindValue(':name', self::getLockName($key), \PDO::PARAM_STR);
9289
$stmt->execute();
9390

94-
unset(self::$locksAcquired[$this->getLockId($key)]);
91+
$key->removeState($this->getStateKey($key));
9592
}
9693

9794
public function exists(Key $key): bool
9895
{
99-
return self::$locksAcquired[$this->getLockId($key)] ?? false;
96+
return $key->hasState($this->getStateKey($key));
10097
}
10198

10299
private function getConnection(): \PDO
@@ -122,13 +119,13 @@ private function assertMysqlDriver(): void
122119
}
123120
}
124121

125-
private function getLockId(Key $key): string
122+
private function getStateKey(Key $key): string
126123
{
127124
if (!isset($this->connectionId)) {
128125
$this->connectionId = $this->getConnection()->query('SELECT CONNECTION_ID()')->fetchColumn();
129126
}
130127

131-
return $this->connectionId.'_'.spl_object_id($key);
128+
return __CLASS__.'_'.$this->connectionId;
132129
}
133130

134131
private static function getLockName(Key $key): string

src/Symfony/Component/Lock/Tests/Store/MysqlStoreTest.php

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,21 +53,52 @@ public function testExceptionModeRequirement()
5353
new MysqlStore($pdo);
5454
}
5555

56-
public function testOtherConflictException()
56+
public function testOtherConnConflictException()
5757
{
5858
$storeA = $this->getStore();
59-
$storeA->save(new Key('foo'));
60-
6159
$storeB = $this->getStore();
6260

61+
$key = new Key('foo');
62+
$storeA->save($key);
63+
64+
$this->assertFalse($storeB->exists($key));
65+
6366
try {
64-
$storeB->save(new Key('foo'));
67+
$storeB->save($key);
6568
$this->fail('Expected exception: '.LockConflictedException::class);
6669
} catch (LockConflictedException $e) {
6770
$this->assertStringContainsString('acquired by other', $e->getMessage());
6871
}
6972
}
7073

74+
public function testExistsOnKeyClone()
75+
{
76+
$store = $this->getStore();
77+
78+
$key = new Key('foo');
79+
$store->save($key);
80+
81+
$this->assertTrue($store->exists($key));
82+
$this->assertTrue($store->exists(clone $key));
83+
}
84+
85+
public function testStoresAreStateless()
86+
{
87+
$pdo = $this->getPdo();
88+
89+
$storeA = new MysqlStore($pdo);
90+
$storeB = new MysqlStore($pdo);
91+
$key = new Key('foo');
92+
93+
$storeA->save($key);
94+
$this->assertTrue($storeA->exists($key));
95+
$this->assertTrue($storeB->exists($key));
96+
97+
$storeB->delete($key);
98+
$this->assertFalse($storeB->exists($key));
99+
$this->assertFalse($storeA->exists($key));
100+
}
101+
71102
public function testDsnConstructor()
72103
{
73104
$this->expectNotToPerformAssertions();

0 commit comments

Comments
 (0)