分散式鎖

在許多情況下,針對某些上下文(甚至單個訊息)的操作必須以排他方式執行。一個示例是聚合器元件,在這種元件中,我們必須檢查當前訊息的訊息組狀態,以確定是釋放該組還是僅新增該訊息以供將來考慮。為此,Java 提供了帶有 java.util.concurrent.locks.Lock 實現的 API。但是,當應用程式分散式執行或在叢集中執行時,問題變得更加複雜。這種情況下的鎖定具有挑戰性,需要一些共享狀態及其特定的方法來滿足排他性要求。Spring Integration 提供了一個 LockRegistry 抽象,其記憶體中實現是基於 ReentrantLock API 的 DefaultLockRegistryLockRegistryobtain(Object) 方法需要一個特定上下文的鎖鍵(lock key)。例如,聚合器使用 correlationKey 來鎖定其組的操作。這樣不同的鎖可以併發使用。這個 obtain(Object) 方法返回一個 java.util.concurrent.locks.Lock 例項(取決於 LockRegistry 實現),因此其餘邏輯與標準 Java 併發演算法相同。

從 6.2 版本開始,LockRegistry 提供了 executeLocked() API(此介面中的預設方法),用於在鎖定狀態下執行某些任務。此 API 的行為類似於眾所周知的 JdbcTemplateJmsTemplateRestTemplate。以下示例演示了此 API 的用法

從 6.2 版本開始,LockRegistry 提供了 executeLocked() API(該介面中的預設方法),用於在鎖定時執行一些任務。這個 API 的行為類似於眾所周知的 JdbcTemplateJmsTemplateRestTemplate。以下示例演示了該 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