Files
breadcrumb-the-shire/lib/Repository/Support/DatabaseSessionRepository.php
fs f4ce9f3378 docs: add class docblocks, business-rule comments, and transaction wrapper
- Add single-line class docblocks to all 59 repository classes and interfaces
  describing scope and responsibility
- Add multi-line docblocks to key services documenting business rules:
  AuthService (6-step login cascade), ImportService (3-phase CSV workflow),
  TenantScopeService (strict/permissive modes), PermissionService (RBAC
  resolution + two-tier caching), UserAccountService (atomicity + audit)
- Add transaction(callable) wrapper to DatabaseSessionRepository to DRY up
  begin/commit/rollback boilerplate

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 21:58:51 +01:00

81 lines
2.2 KiB
PHP

<?php
namespace MintyPHP\Repository\Support;
use MintyPHP\DB;
/** Executes database session operations: advisory locks, transactions, and commit/rollback. */
class DatabaseSessionRepository implements DatabaseSessionRepositoryInterface
{
public function acquireAdvisoryLock(string $lockName, int $timeoutSeconds = 0): bool
{
$lockName = trim($lockName);
if ($lockName === '') {
return false;
}
$timeoutSeconds = max(0, (int) $timeoutSeconds);
$got = DB::selectValue(
'select GET_LOCK(?, ?) as got_lock',
$lockName,
(string) $timeoutSeconds
);
return (int) $got === 1;
}
public function releaseAdvisoryLock(string $lockName): void
{
$lockName = trim($lockName);
if ($lockName === '') {
return;
}
DB::selectValue('select RELEASE_LOCK(?) as released_lock', $lockName);
}
public function beginTransaction(): void
{
DB::handle()->begin_transaction();
}
public function commitTransaction(): void
{
DB::handle()->commit();
}
public function rollbackTransaction(): void
{
DB::handle()->rollback();
}
/**
* Run a callback inside a DB transaction. Commits on success, rolls back on exception.
*
* Eliminates the need for manual begin/commit/rollback + rollbackQuietly() boilerplate
* that is duplicated across multiple services. The callback receives no arguments;
* use closures to capture dependencies.
*
* @template T
* @param callable(): T $callback
* @return T The value returned by the callback.
* @throws \Throwable Re-throws the original exception after rollback.
*/
public function transaction(callable $callback): mixed
{
$this->beginTransaction();
try {
$result = $callback();
$this->commitTransaction();
return $result;
} catch (\Throwable $e) {
try {
$this->rollbackTransaction();
} catch (\Throwable) {
// Swallow — the original exception is more important.
}
throw $e;
}
}
}