1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
|
<?php
declare(strict_types=1);
namespace malkusch\lock\mutex;
use InvalidArgumentException;
use malkusch\lock\exception\LockAcquireException;
use malkusch\lock\exception\TimeoutException;
class MySQLMutex extends LockMutex
{
/**
* @var \PDO
*/
private $pdo;
/**
* @var string
*/
private $name;
/**
* @var int
*/
private $timeout;
public function __construct(\PDO $PDO, string $name, int $timeout = 0)
{
$this->pdo = $PDO;
if (\strlen($name) > 64) {
throw new InvalidArgumentException('The maximum length of the lock name is 64 characters.');
}
$this->name = $name;
$this->timeout = $timeout;
}
/**
* @throws LockAcquireException
*/
public function lock(): void
{
$statement = $this->pdo->prepare('SELECT GET_LOCK(?,?)');
$statement->execute([
$this->name,
$this->timeout,
]);
$statement->setFetchMode(\PDO::FETCH_NUM);
$row = $statement->fetch();
if ($row[0] == 1) {
/*
* Returns 1 if the lock was obtained successfully.
*/
return;
}
if ($row[0] === null) {
/*
* NULL if an error occurred (such as running out of memory or the thread was killed with mysqladmin kill).
*/
throw new LockAcquireException('An error occurred while acquiring the lock');
}
throw TimeoutException::create($this->timeout);
}
public function unlock(): void
{
$statement = $this->pdo->prepare('DO RELEASE_LOCK(?)');
$statement->execute([
$this->name
]);
}
}
|