|
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