accounting workflows
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
<?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]);
|
||||
}
|
||||
}
|
||||
?>
|
||||
Reference in New Issue
Block a user