|
20 | 20 | final class PostgresAdvisoryLocker
|
21 | 21 | {
|
22 | 22 | /**
|
23 |
| - * Acquire transaction-level lock (recommended). |
| 23 | + * Acquire an advisory lock with configurable scope and mode. |
24 | 24 | */
|
25 |
| - public function acquireLockWithinTransaction( |
| 25 | + public function acquireLock( |
26 | 26 | PDO $dbConnection,
|
27 | 27 | PostgresLockId $postgresLockId,
|
28 |
| - PostgresLockModeEnum $lockMode = PostgresLockModeEnum::Try, |
| 28 | + PostgresAdvisoryLockScopeEnum $scope = PostgresAdvisoryLockScopeEnum::Transaction, |
| 29 | + PostgresAdvisoryLockModeEnum $mode = PostgresAdvisoryLockModeEnum::Try, |
29 | 30 | ): bool {
|
30 |
| - if ($dbConnection->inTransaction() === false) { |
31 |
| - $lockId = $postgresLockId->humanReadableValue; |
32 |
| - |
| 31 | + if ($scope === PostgresAdvisoryLockScopeEnum::Transaction && $dbConnection->inTransaction() === false) { |
33 | 32 | throw new LogicException(
|
34 |
| - "Transaction-level advisory lock `$lockId` cannot be acquired outside of transaction", |
| 33 | + "Transaction-level advisory lock `$postgresLockId->humanReadableValue` cannot be acquired outside of transaction", |
35 | 34 | );
|
36 | 35 | }
|
37 | 36 |
|
38 |
| - $sql = match ($lockMode) { |
39 |
| - PostgresLockModeEnum::Try => 'SELECT PG_TRY_ADVISORY_XACT_LOCK(:class_id, :object_id); -- ' . $postgresLockId->humanReadableValue, |
40 |
| - PostgresLockModeEnum::Block => 'SELECT PG_ADVISORY_XACT_LOCK(:class_id, :object_id); -- ' . $postgresLockId->humanReadableValue, |
41 |
| - }; |
42 |
| - |
43 |
| - $statement = $dbConnection->prepare($sql); |
44 |
| - $statement->execute( |
45 |
| - [ |
46 |
| - 'class_id' => $postgresLockId->classId, |
47 |
| - 'object_id' => $postgresLockId->objectId, |
48 |
| - ], |
49 |
| - ); |
50 |
| - |
51 |
| - return $statement->fetchColumn(0); |
52 |
| - } |
53 |
| - |
54 |
| - /** |
55 |
| - * Acquire session-level lock (use only if transaction-level lock not applicable). |
56 |
| - */ |
57 |
| - public function acquireLockWithinSession( |
58 |
| - PDO $dbConnection, |
59 |
| - PostgresLockId $postgresLockId, |
60 |
| - PostgresLockModeEnum $lockMode = PostgresLockModeEnum::Try, |
61 |
| - ): bool { |
62 |
| - $sql = match ($lockMode) { |
63 |
| - PostgresLockModeEnum::Try => 'SELECT PG_TRY_ADVISORY_LOCK(:class_id, :object_id); -- ' . $postgresLockId->humanReadableValue, |
64 |
| - PostgresLockModeEnum::Block => 'SELECT PG_ADVISORY_LOCK(:class_id, :object_id); -- ' . $postgresLockId->humanReadableValue, |
| 37 | + $sql = match ([$scope, $mode]) { |
| 38 | + [PostgresAdvisoryLockScopeEnum::Transaction, PostgresAdvisoryLockModeEnum::Try] => |
| 39 | + 'SELECT PG_TRY_ADVISORY_XACT_LOCK(:class_id, :object_id); -- ' . $postgresLockId->humanReadableValue, |
| 40 | + [PostgresAdvisoryLockScopeEnum::Transaction, PostgresAdvisoryLockModeEnum::Block] => |
| 41 | + 'SELECT PG_ADVISORY_XACT_LOCK(:class_id, :object_id); -- ' . $postgresLockId->humanReadableValue, |
| 42 | + [PostgresAdvisoryLockScopeEnum::Session, PostgresAdvisoryLockModeEnum::Try] => |
| 43 | + 'SELECT PG_TRY_ADVISORY_LOCK(:class_id, :object_id); -- ' . $postgresLockId->humanReadableValue, |
| 44 | + [PostgresAdvisoryLockScopeEnum::Session, PostgresAdvisoryLockModeEnum::Block] => |
| 45 | + 'SELECT PG_ADVISORY_LOCK(:class_id, :object_id); -- ' . $postgresLockId->humanReadableValue, |
65 | 46 | };
|
66 | 47 |
|
67 | 48 | $statement = $dbConnection->prepare($sql);
|
|
0 commit comments