Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Doctrine Datalocking Bundle Laravel Package

webonaute/doctrine-datalocking-bundle

A Symfony bundle that brings data locking to Doctrine entities, helping prevent concurrent modification conflicts and keeping persistence safe with minimal configuration.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

  • Idempotency and duplicate-side-effect prevention. The core capability — atomically "claiming" a set of rows of one entity and handing the caller a lock ID — directly answers the product question "can two workers ever process the same record?" This is the decision behind duplicate emails, double charges, double-posted ledger entries, and duplicated export files.
  • At-least-once vs. exactly-once semantics. Choosing this pattern commits you to at-least-once processing with a claim token; the PM decision is whether the domain can tolerate a retry after a lock expiry, or whether the operation must be made idempotent downstream (e.g., idempotency keys on payments).
  • Build vs. buy for background processing. This is a ~200-line primitive, not a platform. The real decision is "do we adopt a queue/batch framework (SQS, RabbitMQ, Redis + Horizon, Symfony Messenger) or do we keep batch work in the database and coordinate with row locks?" This package represents the "keep it in the DB" branch.
  • Scaling horizon for batch features. Whether statement generation, nightly reconciliation, bulk imports, or report exports can survive running on 2–10 workers. Row-level claiming is sufficient at low volume and becomes a contention problem at high volume — that's a roadmap fork, not an implementation detail.
  • Operational visibility commitments. A lock ID is a claim ticket, so the PM can define support-facing behavior: what happens when a processor dies mid-run, how long a claim lives, and whether an admin can release a stuck batch. Without a decision here, "stuck job" becomes a support ticket class.
  • SLA language for async features. If you promise "report ready within 5 minutes," the claim/retry mechanics determine whether that holds under worker failure.

When to Consider This Package

Consider the pattern (not necessarily this package) when:

  • Your batch work already lives next to the data in a relational DB and you don't want to introduce a broker.
  • You need "one processor handles this list, everyone else skips it" — bulk exports, batch notifications, statement runs, data syncs, reconciliation passes.
  • Volumes are modest (thousands of rows per run, a handful of workers), so SELECT … FOR UPDATE-style contention is not the bottleneck.
  • You want the claim to be transactional with your domain writes (the lock commits or rolls back with the data).

Look elsewhere — or treat this as reference material only — because:

  • It is not a Laravel package. It's a Symfony bundle (DoctrineDataLockingBundle) built on Doctrine ORM/DBAL and the Symfony container. Adopting it in Laravel means pulling in Doctrine plus Symfony bundle wiring, or lifting the logic out. In Laravel, the native equivalents are Cache::lock(), withoutOverlapping(), and lockForUpdate() / skip locked on the query builder — cheaper and already supported.
  • Maintenance risk is the dominant factor. 2 stars, 0 dependents, last release May 2022, MIT. That is a bus factor of one and no evidence of a user base. You would be the only party finding bugs, and Doctrine ORM 3 / Symfony 7 compatibility is unlikely to be handled for you.
  • You need retries, backoff, dead-letter handling, or per-job observability. A lock table gives you none of that; a real queue does.
  • Throughput is high or claim contention is likely. Polling a lock table under load degrades; SKIP LOCKED-based queues or a broker scale better.
  • You need exactly-once side effects, cross-language processors, or claims visible to non-PHP services.

Recommended posture: do not take a production dependency on the package. Use it as a design reference — read the schema and claiming logic, then implement the equivalent in-house (~a few hundred lines: a lock_id, locked_at, locked_by column set plus a token table) or use the platform-native locking primitives. That removes the supply-chain risk while keeping the product benefit.

How to Pitch It (Stakeholders)

To executives: The problem this solves is real and expensive — two workers picking up the same record and charging a customer twice, or sending the same statement email twice. The specific package is not the recommendation: it's a small, unmaintained Symfony component with essentially no adoption, so committing to it would trade a correctness risk for a maintenance risk. The right move is to adopt the pattern — atomically claiming a batch of records with a token before processing — using primitives we already run, and to make the associated product decisions explicit: how long a claim lives, what happens when a worker dies, and which operations must be idempotent. Effort is on the order of one sprint, and it closes a class of duplicate-processing incidents rather than a single bug.

To engineering: Treat webonaute/doctrine-datalocking-bundle as a reference implementation, not a dependency. It requires Doctrine + Symfony bundle wiring, has had no release since May 2022, and has no downstream users — we'd own Doctrine/Symfony version drift ourselves. The mechanism worth copying is the claim-token table: a single UPDATE … WHERE locked_at IS NULL setting a generated lock_id, with processors filtering on that token, and a reaper for stale claims. In Laravel we get most of this from Cache::lock() plus a locked_at/locked_by pair on the entity, or lockForUpdate() for short critical sections. If we later find we need retries, backoff, and dead-letter handling, that's the signal to move the workload onto the queue rather than extend the lock table — please flag contention or stuck-claim metrics as the trigger.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console