quarks/laravel-locking
quarks/laravel-locking brings simple, expressive pessimistic locking to Laravel's Eloquent models, with helpers for exclusive and shared locks so you can safely coordinate concurrent writes and prevent race conditions inside database transactions.
version column is the cheapest correct fix, and this package is a drop-in implementation of that pattern for Eloquent models.409 Conflict (or 412 Precondition Failed) with a machine-readable code — and drive UX copy ("Someone else changed this record; reload to see the latest"). Adopting the pattern forces that contract to be defined deliberately rather than discovered in production.SELECT ... FOR UPDATE for high-contention counters. A PM decision to adopt it should explicitly exclude those problems from its remit so nobody assumes concurrency is "solved."Consider it (or, more precisely, the pattern it implements) when all of the following hold:
Look elsewhere (or build in-house) when:
SELECT ... FOR UPDATE, atomic UPDATE ... WHERE version = ? with retry budgeting, or a serialized write path.webpatser/laravel-uuid-style versioning, Spatie-style audit/versioning packages, or Laravel's own lockForUpdate primitives plus a hand-rolled trait).Practical recommendation: do not composer require this as a production dependency. Read it, extract the trait and migration stub, add tests for the conflict path, and own it. That converts a 0.115-score dependency into ~150 lines of first-party code with the same product benefit and none of the abandonment risk.
To executives (one paragraph): We have a class of bugs where two people edit the same record at the same time and one person's work silently disappears — it shows up as data corruption, support tickets, and occasionally financial or inventory discrepancies. The standard fix is optimistic locking: every record carries a version number, and a save only succeeds if nobody else changed it in the meantime; otherwise the user is told to reload. This package implements that pattern for our Laravel stack under an MIT license. It is small and unmaintained, so my recommendation is to adopt the pattern, not the dependency — roughly one sprint-day of engineering to implement first-party, with lasting protection on our highest-value tables. It is cheap, well-understood, and eliminates a whole category of incidents.
To engineering: The package is a version-column optimistic lock for Eloquent — WHERE id = ? AND version = ? on update, throw/increment on mismatch. Do not take it as a dependency: last release July 2022, no dependents, no evidence of Laravel 10/11 support, and it sits on the hot path of every write. Use it as a spec. We implement a HasOptimisticLock trait ourselves, add version unsigned integers with sensible defaults to the tables that need it, define the 409 Conflict API contract and the front-end "reload" flow, and write tests that simulate two concurrent writers. Also be explicit about what this is not: it does not replace transactions, unique constraints, idempotency keys, or row-level locks for high-contention writes. Budget the work as a schema decision plus a trait plus a UX contract — not as an integration.
How can I help you explore Laravel packages today?