Skip to content

Continue API improvement #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Aug 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 39 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
<a href="https://github.com/cybercog/php-db-locker/blob/master/LICENSE"><img src="https://img.shields.io/github/license/cybercog/php-db-locker.svg?style=flat-square" alt="License"></a>
</p>

## Things to decide

- [ ] Should wait mode be blocking or non-blocking by default?
- [ ] Should callback for session lock be at the end of the params (after optional ones)?

## Introduction

> WARNING! This library is currently under development and may not be stable. Use in your services at your own risk.
Expand Down Expand Up @@ -38,7 +43,7 @@ $locker = new \Cog\DbLocker\Postgres\PostgresAdvisoryLocker();
$lockId = \Cog\DbLocker\Postgres\PostgresLockKey::create('user', '4');

$dbConnection->beginTransaction();
$lock = $locker->acquireSessionLevelLockHandler(
$lock = $locker->acquireSessionLevelLock(
$dbConnection,
$lockId,
\Cog\DbLocker\Postgres\Enum\PostgresLockWaitModeEnum::NonBlocking,
Expand All @@ -54,18 +59,45 @@ $dbConnection->commit();

#### Session-level advisory lock

Callback API

```php
$dbConnection = new PDO($dsn, $username, $password);

$locker = new \Cog\DbLocker\Postgres\PostgresAdvisoryLocker();
$lockId = \Cog\DbLocker\Postgres\PostgresLockKey::create('user', '4');
$lockKey = \Cog\DbLocker\Postgres\PostgresLockKey::create('user', '4');

$payment = $locker->withinSessionLevelLock(
dbConnection: $dbConnection,
key: $lockKey,
callback: function (
\Cog\DbLocker\Postgres\LockHandle\SessionLevelLockHandle $lock,
): Payment { // Define a type of $payment variable, so it will be resolved by analyzers
if ($lock->wasAcquired) {
// Execute logic if lock was successful
} else {
// Execute logic if lock acquisition has been failed
}
},
waitMode: \Cog\DbLocker\Postgres\Enum\PostgresLockWaitModeEnum::NonBlocking,
accessMode: \Cog\DbLocker\Postgres\Enum\PostgresLockAccessModeEnum::Exclusive,
);
```

Low-level API

```php
$dbConnection = new PDO($dsn, $username, $password);

$locker = new \Cog\DbLocker\Postgres\PostgresAdvisoryLocker();
$lockKey = \Cog\DbLocker\Postgres\PostgresLockKey::create('user', '4');

try {
$lock = $locker->acquireSessionLevelLockHandler(
$dbConnection,
$lockId,
\Cog\DbLocker\Postgres\Enum\PostgresLockWaitModeEnum::NonBlocking,
\Cog\DbLocker\Postgres\Enum\PostgresLockAccessModeEnum::Exclusive,
$lock = $locker->acquireSessionLevelLock(
dbConnection: $dbConnection,
key: $lockKey,
waitMode: \Cog\DbLocker\Postgres\Enum\PostgresLockWaitModeEnum::NonBlocking,
accessMode: \Cog\DbLocker\Postgres\Enum\PostgresLockAccessModeEnum::Exclusive,
);
if ($lock->wasAcquired) {
// Execute logic if lock was successful
Expand Down
8 changes: 4 additions & 4 deletions src/Postgres/Enum/PostgresLockAccessModeEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
/**
* PostgresLockAccessModeEnum defines the access mode of advisory lock acquisition.
*
* TODO: Need string values only for tests, should add match to tests instead.
* TODO: Write details about access mode.
*/
enum PostgresLockAccessModeEnum: string
enum PostgresLockAccessModeEnum
{
case Exclusive = 'ExclusiveLock';
case Share = 'ShareLock';
case Exclusive;
case Share;
}
12 changes: 6 additions & 6 deletions src/Postgres/Enum/PostgresLockLevelEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@
/**
* PostgresLockLevelEnum defines the level of advisory lock acquisition.
*
* - Transaction. Transaction-level (recommended) advisory lock (with _XACT_):
* - PG_ADVISORY_XACT_LOCK
* - PG_ADVISORY_XACT_LOCK_SHARED
* - PG_TRY_ADVISORY_XACT_LOCK
* - PG_TRY_ADVISORY_XACT_LOCK_SHARED
* - Session. Session-level advisory lock (without _XACT_):
* - PG_ADVISORY_LOCK
* - PG_ADVISORY_LOCK_SHARED
* - PG_TRY_ADVISORY_LOCK
* - PG_TRY_ADVISORY_LOCK_SHARED
* - Transaction. Transaction-level advisory lock (with _XACT_):
* - PG_ADVISORY_XACT_LOCK
* - PG_ADVISORY_XACT_LOCK_SHARED
* - PG_TRY_ADVISORY_XACT_LOCK
* - PG_TRY_ADVISORY_XACT_LOCK_SHARED
*/
enum PostgresLockLevelEnum
{
case Session;
case Transaction;
case Session;
}
10 changes: 5 additions & 5 deletions src/Postgres/Enum/PostgresLockWaitModeEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@
/**
* PostgresLockWaitModeEnum defines the type of advisory lock acquisition.
*
* - NonBlocking. Attempt to acquire the lock without blocking (with _TRY_):
* - PG_TRY_ADVISORY_LOCK
* - PG_TRY_ADVISORY_LOCK_SHARED
* - PG_TRY_ADVISORY_XACT_LOCK
* - PG_TRY_ADVISORY_XACT_LOCK_SHARED
* - Blocking. Acquire the lock, blocking until it becomes available (without _TRY_):
* - PG_ADVISORY_LOCK
* - PG_ADVISORY_LOCK_SHARED
* - PG_ADVISORY_XACT_LOCK
* - PG_ADVISORY_XACT_LOCK_SHARED
* - NonBlocking. Attempt to acquire the lock without blocking (with _TRY_):
* - PG_TRY_ADVISORY_LOCK
* - PG_TRY_ADVISORY_LOCK_SHARED
* - PG_TRY_ADVISORY_XACT_LOCK
* - PG_TRY_ADVISORY_XACT_LOCK_SHARED
*/
enum PostgresLockWaitModeEnum
{
Expand Down
13 changes: 2 additions & 11 deletions src/Postgres/LockHandle/SessionLevelLockHandle.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ final class SessionLevelLockHandle
public function __construct(
private readonly PDO $dbConnection,
private readonly PostgresAdvisoryLocker $locker,
public readonly PostgresLockKey $lockId,
public readonly PostgresLockKey $lockKey,
public readonly PostgresLockAccessModeEnum $accessMode,
public readonly bool $wasAcquired,
) {}
Expand All @@ -49,7 +49,7 @@ public function release(): bool

$wasReleased = $this->locker->releaseSessionLevelLock(
$this->dbConnection,
$this->lockId,
$this->lockKey,
);

if ($wasReleased) {
Expand All @@ -58,13 +58,4 @@ public function release(): bool

return $wasReleased;
}

/**
* Automatically release the lock when the handle is destroyed.
*/
public function __destruct()
{
// TODO: Do we need to
$this->release();
}
}
24 changes: 0 additions & 24 deletions src/Postgres/LockHandle/TransactionLevelLockHandle.php

This file was deleted.

Loading
Loading