分布式锁
在许多情况下,针对某些上下文(甚至单个消息)的操作必须以独占方式执行。一个例子是聚合器组件,我们必须检查当前消息的消息组状态,以确定我们是否可以释放该组,或者只是将该消息添加到未来考虑中。为此,Java 提供了一个带有java.util.concurrent.locks.Lock
实现的 API。但是,当应用程序分布式和/或在集群中运行时,问题变得更加复杂。在这种情况下,锁定具有挑战性,需要一些共享状态及其特定方法来实现排他性要求。
Spring Integration 提供了一个LockRegistrty
抽象,它基于ReentrantLock
API 提供了一个内存中的DefaultLockRegistry
实现。LockRegistrty
的obtain(Object)
方法需要一个特定上下文的锁键
。例如,聚合器使用correlationKey
来锁定其组周围的操作。这样,不同的锁可以并发使用。此obtain(Object)
方法返回一个java.util.concurrent.locks.Lock
实例(取决于LockRegistry
实现),因此其余逻辑与标准 Java 并发算法相同。
从 6.2 版本开始,LockRegistry
提供了一个executeLocked()
API(此接口中的default
方法)来执行锁定时的某些任务。此 API 的行为类似于众所周知的JdbcTemplate
、JmsTemplate
或RestTemplate
。以下示例演示了此 API 的用法。
LockRegistry registry = new DefaultLockRegistry();
...
registry.executeLocked("someLockKey", () -> someExclusiveResourceCall());
该方法会重新抛出任务调用中的异常,如果Lock
被中断则抛出InterruptedException
。此外,带有Duration
的变体在lock.tryLock()
返回false
时会抛出java.util.concurrent.TimeoutException
。
Spring Integration 为分布式锁提供以下LockRegistrty
实现:
Spring Integration AWS 扩展也实现了DynamoDbLockRegistry
。