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