Concurrency guard for Django using PostgreSQL advisory locks.
Project description
django-concurrency-safe
Concurrency guard for Django using PostgreSQL advisory locks.
Prevent race conditions in critical sections using simple, expressive decorators or context managers.
Why?
Race conditions are easy to introduce and hard to detect.
Example:
def withdraw(user, amount):
if user.balance >= amount:
user.balance -= amount
user.save()
Two concurrent requests can both pass the balance check and withdraw twice.
This library prevents that.
Features
- PostgreSQL advisory lock backend
- Simple decorator API
- Context manager support
- Business-key locking (not limited to database rows)
- Timeout and conflict handling
Installation
pip install django-concurrency-safe
Quickstart
Import:
from concurrency_safe import concurrency_safe, lock, LockAcquireTimeout
Using the decorator
@concurrency_safe(key="withdraw:user:{user_id}")
def withdraw(user_id, amount):
...
Only one execution per key runs at a time.
Using the context manager
with lock("stock:ABC"):
process_order()
Conflict handling
When the lock cannot be acquired:
@concurrency_safe(key="stock:{sku}")
Raises LockAcquireTimeout by default.
Custom handler:
from django.http import JsonResponse
def busy(*args, **kwargs):
return JsonResponse({"detail": "busy"}, status=409)
@concurrency_safe(
key="stock:{sku}",
on_conflict=busy,
)
Example project
example/ contains a runnable Django demo showcasing the race condition, row-level locks, and advisory locks (PostgreSQL).
Why advisory locks?
Unlike row-level locking, advisory locks:
- Work without locking a specific database row
- Support arbitrary business keys
- Are fast and lightweight
- Automatically release on connection close
Requirements
- Python 3.10+
- Django 4.2+
- PostgreSQL
Roadmap
- Redis backend
- Async support
- Metrics hooks
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file django_concurrency_safe-0.0.1.tar.gz.
File metadata
- Download URL: django_concurrency_safe-0.0.1.tar.gz
- Upload date:
- Size: 10.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f4696c2f2b43a4072092b76876ff752893f60fbb4c7768c7877e0c9da19f8c9c
|
|
| MD5 |
3fbe1e7574a5f5acaa35325484b8f388
|
|
| BLAKE2b-256 |
aef607240184f98c40a8458d25f47fd97c495fcfd534360010464690955d19bf
|
File details
Details for the file django_concurrency_safe-0.0.1-py3-none-any.whl.
File metadata
- Download URL: django_concurrency_safe-0.0.1-py3-none-any.whl
- Upload date:
- Size: 9.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2912a9316e1ce3d0bf93dd618fe0e4868b888e8f1b39c93aaeaa2b4d048970ba
|
|
| MD5 |
c52799799b355cfbc4766ceb22a449ca
|
|
| BLAKE2b-256 |
6eb479aced8244351fa39dc68654ed7265d7ccbb6c31e5f19675a729dfe5ddf3
|