You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WSO2 ESB中Iterator与Script Mediator计算成绩求和异常问题

WSO2 ESB Iterator Mediator累加成绩总和异常解决方法

问题现象

使用Iterator Mediator遍历学生成绩,配合Script Mediator累加totalnote变量时,无法实现持续累加效果:每次计算都是初始值与当前成绩直接相加,而非基于上一次的累加结果继续计算。例如初始值设为0时,日志显示ms值为13、15、16、17,而非预期的13→28→44→61。

问题原因

Iterator Mediator默认采用多线程并行处理每个迭代分支,每个分支在执行时都会读取totalnote的初始值,分支之间的变量修改互相隔离,无法共享更新后的结果,导致累加失效。

解决方案

方案1:开启Iterator顺序执行模式

通过为Iterator添加sequential="true"属性,强制迭代分支按顺序单线程执行,这样每个分支都能获取到上一次修改后的totalnote值,实现正常累加。

修改后的核心配置:

<property name="totalnote" scope="default" type="INTEGER" value="0"/>
<!-- 开启顺序迭代,确保分支按顺序执行 -->
<iterate expression="//etudiants/etudiant" sequential="true">
    <target>
        <sequence>
            <property expression="json-eval($.etudiant.note)" name="note" scope="default" type="INTEGER"/>
            <log level="custom">
                <property expression="get-property('note')" name="msg"/>
            </log>
            <script language="js"><![CDATA[
                var i = parseInt(mc.getProperty("note"));
                var totalnote = parseInt(mc.getProperty("totalnote"));         
                totalnote += i;
                mc.setProperty("totalnote", totalnote.toString());
            ]]></script>
            <log level="custom">
                <property expression="get-property('totalnote')" name="ms"/>
            </log>
        </sequence>
    </target>
</iterate>
<respond/>

方案2:使用Aggregate Mediator聚合计算

若需保留Iterator的并行处理性能(适合数据量大的场景),可在迭代分支中收集单个成绩,最后通过Aggregate Mediator汇总所有成绩并计算总和。

示例配置:

<property name="totalnote" scope="default" type="INTEGER" value="0"/>
<iterate expression="//etudiants/etudiant" id="studentIterator">
    <target>
        <sequence>
            <property expression="json-eval($.etudiant.note)" name="note" scope="default" type="INTEGER"/>
            <log level="custom">
                <property expression="get-property('note')" name="msg"/>
            </log>
            <!-- 将当前成绩封装为JSON消息,供聚合器收集 -->
            <payloadFactory media-type="json">
                <format>{"note": $1}</format>
                <args>
                    <arg evaluator="xml" expression="$ctx:note"/>
                </args>
            </payloadFactory>
            <send>
                <endpoint><default/></endpoint>
            </send>
        </sequence>
    </target>
</iterate>

<!-- 聚合所有分支结果并计算总和 -->
<aggregate id="studentIterator">
    <completeCondition>
        <messageCount max="-1" min="-1"/>
    </completeCondition>
    <onComplete expression="//jsonObject">
        <script language="js"><![CDATA[
            var noteList = mc.getPayloadJSON().jsonObject;
            var total = 0;
            noteList.forEach(function(item) {
                total += parseInt(item.note);
            });
            mc.setProperty("totalnote", total.toString());
        ]]></script>
        <log level="custom">
            <property expression="get-property('totalnote')" name="最终成绩总和"/>
        </log>
        <respond/>
    </onComplete>
</aggregate>

方案对比

  • 方案1:配置简单,单线程执行无并发问题,适合数据量较小的场景
  • 方案2:保留并行处理能力,聚合阶段统一计算,性能更优,适合数据量大的场景

内容的提问来源于stack exchange,提问作者rania ben salem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 12:25:25