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

调度器与Batchable执行异常:部分记录未按预期更新

Salesforce调度Batch更新部分记录失效问题排查

问题场景

  • 配置每日午夜执行的调度作业,用于更新约7000条XXX记录(依赖自动化逻辑更新,无手动数据录入),但其中约150条未按预期完成更新
  • 匿名Apex中单独或批量调用update/Database.update()操作这些异常记录,可正常更新;但通过匿名Apex调用调度器触发Batch类时,更新失效
  • 调度作业执行用户与调试用的用户为同一账号

相关代码

Batchable类代码

global Database.QueryLocator start(Database.BatchableContext BC){
        return Database.getQueryLocator([SELECT Id, Name FROM XXX ]);
}

global void execute(Database.BatchableContext BC, List<XXX> scopePolicy){
        Database.update(scopePolicy, false);
}

global void finish(Database.BatchableContext BC){
}

Schedulable类代码

global void execute(SchedulableContext SC) {
        try{
            XXX xxx = new XXX();
            database.executebatch(xxx, 15);
        }
        catch (DmlException e)  {}
    }

问题解答

1. Batchable是否使用独立API?

Batch Apex属于Salesforce后台异步执行框架,不会消耗组织的API调用额度,它是内部异步执行通道,和外部REST/SOAP API不属于同一类,但执行时的权限上下文基于触发Batch的用户。

2. 调度器或Batchable是否会产生与直接更新不同的执行设置?

是的,存在以下关键差异点,也是导致部分记录更新失效的核心排查方向:

  • 批量执行上下文:Batch的execute方法每次处理15条记录(你设置的批量大小),而匿名Apex直接更新时的批量大小可能不同。如果XXX对象的触发器、流程或验证规则中存在依赖Trigger.size这类批量大小的逻辑,就会导致行为差异。
  • 错误处理逻辑:Batch中使用Database.update(scopePolicy, false)会跳过更新失败的记录但不抛出异常;同时调度器的try-catch吞了DmlException,导致你无法看到Batch执行中的错误日志。而匿名Apex直接更新时,若未设置allOrNone=false,会直接抛出异常暴露问题。
  • 查询字段完整性:Batch的start方法只查询了Id和Name字段,如果XXX对象的自动化更新逻辑(触发器、流程)依赖其他字段的值,Batch传递给execute的记录中这些字段为null,会导致自动化逻辑不触发或执行异常;而匿名Apex直接更新时你可能查询了完整字段,所以逻辑正常。
  • 异步执行的细微差异:虽然用户相同,但异步执行(Batch/Scheduler)的共享规则检查、事务上下文可能存在极细微差异,但这个概率极低,优先排查前面的点。

排查建议

  • 在Batch的execute方法中添加日志,捕获并输出更新结果:
    global void execute(Database.BatchableContext BC, List<XXX> scopePolicy){
            Database.SaveResult[] results = Database.update(scopePolicy, false);
            for(Database.SaveResult res : results){
                if(!res.isSuccess()){
                    System.debug('更新失败记录ID: ' + res.getId() + ' 错误信息: ' + res.getErrors()[0].getMessage());
                }
            }
    }
    
  • 检查XXX对象的触发器、流程、验证规则,确认是否存在依赖批量大小或特定字段的逻辑
  • 扩大Batch查询的字段范围,包含自动化更新逻辑所需的所有字段,比如:
    return Database.getQueryLocator([SELECT Id, Name, 字段1, 字段2 FROM XXX ]);
    
  • 移除调度器中吞掉异常的try-catch,或在catch中添加日志,避免隐藏错误

内容的提问来源于stack exchange,提问作者seekingPeace

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 02:10:15