Files
wms-app/app/assets/utils/classes/OperationLockManager.php
2026-05-20 10:17:02 +07:00

82 lines
2.6 KiB
PHP

<?php
class OperationLockManager
{
private PDO $pdo;
private int $companyId;
private int $userId;
public function __construct(PDO $pdo, int $company_id, int $user_id)
{
$this->pdo = $pdo;
$this->companyId = $company_id;
$this->userId = $user_id;
}
public function acquire(string $operation_type, int $ttl_minutes = 120): array
{
$operation_type = trim($operation_type);
$ttl_minutes = max(1, min(480, $ttl_minutes));
if ($operation_type === '') {
throw new Exception('operation_type is required.');
}
$now = date('Y-m-d H:i:s');
$expires = date('Y-m-d H:i:s', strtotime("+{$ttl_minutes} minutes"));
$this->pdo->beginTransaction();
try {
$sth = $this->pdo->prepare(
"SELECT * FROM md_lock_operation
WHERE company_id = :cid AND operation_type = :op_type
FOR UPDATE"
);
$sth->execute([':cid' => $this->companyId, ':op_type' => $operation_type]);
$lock = $sth->fetch(PDO::FETCH_ASSOC);
if ($lock) {
$this->pdo->rollBack();
return [
'success' => 0,
'message' => 'Operation "' . $operation_type . '" is already running. Please wait.',
'expires_at' => $lock['expires_at'],
'locked_at' => $lock['locked_at'],
];
}
$this->pdo->prepare(
"INSERT INTO md_lock_operation (company_id, operation_type, user_id, locked_at, expires_at)
VALUES (:cid, :op_type, :uid, :locked_at, :expires_at)"
)->execute([
':cid' => $this->companyId,
':op_type' => $operation_type,
':uid' => $this->userId,
':locked_at' => $now,
':expires_at' => $expires,
]);
$this->pdo->commit();
return ['success' => 1, 'message' => 'Lock acquired.'];
} catch (Throwable $e) {
if ($this->pdo->inTransaction()) $this->pdo->rollBack();
throw $e;
}
}
public function release(string $operation_type): void
{
$operation_type = trim($operation_type);
if ($operation_type === '') {
throw new Exception('operation_type is required.');
}
$this->pdo->prepare(
"DELETE FROM md_lock_operation
WHERE company_id = :cid AND operation_type = :op_type"
)->execute([':cid' => $this->companyId, ':op_type' => $operation_type]);
}
}
?>