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