2

Retry を使用した次の Spring Integration 構成があります。

<int:chain input-channel="sdCreationChannel" output-channel="debugLogger">
    <int:poller fixed-delay="500" />
    <int:filter ref="sdIntegrationExistingRequestSentFilter" method="filter"/>
    <int:service-activator ref="sdCreationServiceImpl" method="processMessage">
        <int:request-handler-advice-chain>
            <ref bean="retryAdvice"/>
        </int:request-handler-advice-chain>
    </int:service-activator>
</int:chain>

<bean id="retryAdvice" class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice" >
    <property name="retryTemplate">
        <bean class="org.springframework.retry.support.RetryTemplate">
            <property name="backOffPolicy">
                <bean class="org.springframework.retry.backoff.ExponentialBackOffPolicy">
                    <property name="initialInterval" value="${integration.retry.initial.delay}"/>
                    <property name="multiplier" value="${integration.retry.backoff.multiplier}"/>
                </bean>
            </property>
            <property name="retryPolicy">
                <bean class="org.springframework.retry.policy.SimpleRetryPolicy">
                    <property name="maxAttempts" value="${integration.retry.max.attempts}" />
                </bean>
            </property>
        </bean>
    </property>
</bean>

簡略化された Java コードは次のとおりです。

@Component("sdCreationServiceImpl")
public class SDCreationServiceImpl implements SDCreationService {

@Autowired
private NotifySD  notifySD;
@Override
public void processMessage(IntegrationPayload integrationPayload) {
List<ConfirmationCode> sdConfCodes = findCodesFromPayLoad(integrationPayload);
    notifySD.activateConfirmationCodes(sdConfCodes);

}  

このコードを再試行する際の問題は、List sdConfCodes が再試行のたびに部分的に処理される可能性があるため、処理のために送信する必要があるたびに、より少ない量の要素を処理する必要があることです。このコードを整理する最良の方法は何ですか?

Artem Bilan の提案 (ありがとう!) に従って、SDCreationServiceImpl の変数リストを使用して 2 番目のメソッド、つまり activateConfirmationCodes を作成し、XML 仕様でこのメソッドを sdCreationServiceImpl のメソッドとして指定しました。

@Component("sdCreationServiceImpl")
public class SDCreationServiceImpl implements SDCreationService {
@Autowired
private NotifySD  notifySD;
List<ConfirmationCode> sdConfCodes = new ArrayList<ConfirmationCode()>;
@Override
public void processMessage(IntegrationPayload integrationPayload) {
sdConfCodes = findCodesFromPayLoad(integrationPayload);
}  

public void activateConfirmationCodes()
{
    notifySD.activateConfirmationCodes(sdConfCodes);
}

そして、service-activator の XML 仕様は次のとおりです。

<int:service-activator ref="sdCreationServiceImpl" method="activateConfirmationCodes">
<int:request-handler-advice-chain>
<ref bean="retryAdvice"/>
</int:request-handler-advice-chain>
</int:service-activator>

はい、このメソッド activateConfirmationCodes は Retry で呼び出されますが、最初のメソッド processMessage はまったく呼び出されません。最初の試行で呼び出す方法を 1 つ指定し、再試行する方法を別の方法で指定することはできますか? この設計では、リストがシングルトンになり、マルチスレッドで問題が発生する可能性がありますね。このリストを特定のメッセージのみの Bean に関連付けることはできますか?

4

1 に答える 1

2

大きな問題から、どこに問題があるのか​​ は明確ではありません。反対側から、私の考えを共有させてください。おそらく、あなたの目標を推測します。

List<ConfirmationCode>として持つpayloadことで、いつでも変更できます。10では、リストを要素として持っているとしましょう。最初の試行で、そのうちの 3 つを処理しました。4回目は失敗。適切な例外のスローを再試行する必要があります。しかし、再試行対応メソッドの最初に戻るので、同じ引数を使用します。これらの成功したアイテムをコレクションから削除すると、次の再試行の反復でそれらがまったく処理されなくなります。

一方で、その際立っfindCodesFromPayLoad()たサービスとを実現しactivateConfirmationCodes()、最後のサービスに再試行を適用できます。

反対側から、アイテムを で処理済みとしてマークできるactivateConfirmationCodes()ため、次のアイテムfindCodesFromPayLoad(integrationPayload)は返されません。

つまり、メッセージを変更せずにコレクションを変更する方法はいくらでもあります。

于 2016-01-11T20:22:16.317 に答える