Exclusive & Read/Write locking based on MySQL Locking Service
- php >= 7.1
- PDO extension
Need to install the locking service UDFs as described in MySQL docs:
https://dev.mysql.com/doc/refman/8.0/en/locking-service-udf-interface.html
composer require team-a/lock:^1.2.0
- Inject PDO instance promise. You can create lazy instance of PDO.
$serviceManager = $this->getServiceManager();
AbstractDb::setPdoPromise(
function() use ($serviceManager) : \PDO
{
return $serviceManager->getPDO();
}
);
-
Define and use your own lock class based on TeamA\Lock\AbstractDBExclusive or TeamA\Lock\AbstractDBExtended.
-
Exclusive lock example:
class Point extends AbstractDbExclusive
{
protected function __construct(
int $providerId,
? string $providerPointId,
? string $providerPointEssentialId
)
{
parent::__construct([
$providerId, $providerPointId, $providerPointEssentialId
]);
}
}
/* ... */
$pointLock = new Point($pId, $pPointId, null);
try {
$pointLock->lock();
$this->_db->beginTransaction();
// do smth.
$this->_db->commit();
return true;
} catch (TeamA\Lock\TimeoutException $e) {
return false;
} catch (\Exception $e) {
$this->_db->rollback();
throw $e;
} finally {
$pointLock->releaseIfLocked();
}
- Read/Write locking example:
class GeoBinding extends AbstractDbExtended
{
public function __construct(int $departureProviderId)
{
parent::__construct(func_get_args());
}
}
/* ... */
$lock = new GeoBinding(static::_getProviderId());
try {
$lock->lockWrite();
$this->_db->beginTransaction();
// do smth.
$this->_db->commit();
return true;
} catch (TeamA\Lock\TimeoutException $e) {
return false;
} catch (\Exception $e) {
$this->_db->rollback();
throw $e;
} finally {
$lock->release();
}
/* ... */
$lock = new GeoBinding(static::_getProviderId());
try {
$lock->lockRead();
$this->_db->beginTransaction();
// do smth. else...