#[Lockable] you guarantee that only one caller can execute that method at a time — either at the local-node level (default) or across an entire cluster when a distributed LockManager is provided. Parameter expressions such as name: "order-#{id}" allow the lock scope to be narrowed down to a specific resource instance, preventing unnecessary serialization of unrelated requests.
#[Lockable] Options
string
required
Unique name for the lock. Supports
#{param} interpolation to bind method parameters into the lock name (e.g. "order-#{id}").string
default:"Framework default"
Bean name of a class implementing
LockManager. Omit to use local node locking.int
default:"0"
How long (in milliseconds) to wait for the lock before failing.
0 means fail immediately if the lock is not available.int
default:"0"
Maximum time (in seconds) the lock is held before it is automatically released.
0 means no TTL limit.Local Node Locking
The framework provides local node locking out of the box — no extra configuration or bean is needed. Only one process on the same node can execute the annotated method at a time. The#{id} syntax binds the method parameter $id into the lock name, so two concurrent calls with different order IDs proceed in parallel while two calls for the same ID are serialized.
- Basic Lock
- With Wait Timeout
OrderService.php
Distributed Locking
For deployments with multiple nodes you need aLockManager backed by a shared store so that locks are visible across the entire cluster. Provide a bean that implements LockManager, pass its bean name to the lockManager option, and the #[Lockable] attribute works identically to local locking from your code’s perspective.
Supported backends include Redis, database locks, Apache ZooKeeper, Consul, and anything else you can wrap in a LockManager implementation.
1
Annotate the method with a named lockManager
OrderService.php
2
Register the LockManager bean
LockConfig.php
The Symfony Lock component supports Redis, Memcached, PDO/DBAL databases, ZooKeeper, Consul, and more — all of which can be adapted to the Winter Boot
LockManager interface.Handling LockException
If the lock cannot be acquired withinwaitMilliSecs milliseconds, Winter Boot throws a LockException. Catch it in your controller or service layer and return an appropriate response to the caller.
OrderController.php
Common LockException scenarios
Common LockException scenarios