このバージョンはまだ開発中であり、まだ安定しているとは見なされていません。最新の安定バージョンについては、Spring Integration 6.5.3 を使用してください!

ロックアドバイス

バージョン 6.5 以降、LockRequestHandlerAdvice が導入されました。このアドバイスは、リクエストメッセージに対してロックキーを評価し、LockRegistry.executeLocked() API を実行します。このアドバイスの目的は、lockKey コンテキストに従ってサービス呼び出しへの排他的アクセスを実現することです。つまり、異なるキーがサービスに同時にアクセスできる可能性があります。

LockRequestHandlerAdvice には、LockRegistry と、静的、SpEL、関数ベースのロックキーコールバックが必要です。lockKey が null と評価された場合、サービス呼び出しの前後でロックは保持されません。ただし、discardChannel を指定することもできます。その場合、代わりに null キーを持つメッセージがこのチャネルに送信されます。また、Lock.lockInterruptibly() の代わりに Lock.tryLock(long, TimeUnit) API を使用するために、waitLockDuration オプションを指定することもできます。

以下は LockRequestHandlerAdvice の使用方法のサンプルです。

@Bean
LockRegistry lockRegistry() {
    return new DefaultLockRegistry();
}

@Bean
QueueChannel discardChannel() {
    return new QueueChannel();
}

@Bean
LockRequestHandlerAdvice lockRequestHandlerAdvice(LockRegistry lockRegistry, QueueChannel discardChannel) {
    LockRequestHandlerAdvice lockRequestHandlerAdvice =
            new LockRequestHandlerAdvice(lockRegistry, (message) -> message.getHeaders().get(LOCK_KEY_HEADER));
    lockRequestHandlerAdvice.setDiscardChannel(discardChannel);
    lockRequestHandlerAdvice.setWaitLockDurationExpressionString("'PT1s'");
    return lockRequestHandlerAdvice;
}

AtomicInteger counter = new AtomicInteger();

@ServiceActivator(inputChannel = "inputChannel", adviceChain = "lockRequestHandlerAdvice")
String handleWithDelay(String payload) throws InterruptedException {
    int currentCount = this.counter.incrementAndGet();
    Thread.sleep("longer_process".equals(payload) ? 2000 : 500);
    try {
        return payload + "-" + currentCount;
    }
    finally {
        this.counter.decrementAndGet();
    }
}