39 lines
1.1 KiB
PHP
39 lines
1.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace MonetaPhpShop\host;
|
|
|
|
use MonetaPhpShop\callback\OrderLock;
|
|
|
|
/**
|
|
* Áëîêèðîâêà çàêàçà ÷åðåç `GET_LOCK` MySQL: òàáëèöû PHPShop — MyISAM, òðàíçàêöèé íåò.
|
|
* Èìÿ áëîêèðîâêè îáùåå äëÿ ñåðâåðà MySQL, ïîýòîìó â íåãî âõîäèò èìÿ áàçû: äâà ìàãàçèíà
|
|
* íà îäíîì ñåðâåðå äðóã äðóãà íå æäóò. Áëîêèðîâêà ñíèìàåòñÿ è ïðè îáðûâå ñîåäèíåíèÿ.
|
|
*/
|
|
final class MysqlOrderLock implements OrderLock
|
|
{
|
|
/** Ñêîëüêî æäàòü ïàðàëëåëüíîå óâåäîìëåíèå ïî òîìó æå çàêàçó, ñåêóíä. */
|
|
private const TIMEOUT = 10;
|
|
|
|
private const NAME = "CONCAT('moneta_', MD5(CONCAT(DATABASE(), ':', ?)))";
|
|
|
|
/** @var Database */
|
|
private $database;
|
|
|
|
public function __construct(Database $database)
|
|
{
|
|
$this->database = $database;
|
|
}
|
|
|
|
public function acquire(int $orderId): bool
|
|
{
|
|
return (int) $this->database->fetchValue('SELECT GET_LOCK(' . self::NAME . ', ?)', [$orderId, self::TIMEOUT]) === 1;
|
|
}
|
|
|
|
public function release(int $orderId): void
|
|
{
|
|
$this->database->fetchValue('SELECT RELEASE_LOCK(' . self::NAME . ')', [$orderId]);
|
|
}
|
|
}
|