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

Flow Action中Database相关方法失效引发Callout异常求助

问题分析与解决方案

问题根源

时间触发式Flow(Schedule-Triggered Flow)的执行上下文里,Salesforce会自动启动一个事务,且在调用你的Invocable方法前,已经存在隐式的未提交工作(比如Flow执行日志的记录操作)。即便你没主动执行任何DML,这个隐式事务也会导致后续外部调用触发System.CalloutException——Salesforce不允许在存在未提交工作的事务中发起callout,而你手动设置保存点回滚的操作,无法清除Flow上下文自带的未提交事务状态。

而匿名执行环境是独立事务,不存在这些隐式操作,因此代码能正常运行。

解决方案

方案1:将Callout逻辑移至异步方法

在Invocable方法中调用带@Future(callout=true)的异步方法,把callout逻辑放到异步上下文执行——异步上下文是独立事务,不受Flow主事务的影响。

修改后的代码示例:

@InvocableMethod(label='Test Database Rollback with Callout in a Flow' callout=true)
global static List<List<String>> testDatabaseRollback() {
    List<List<String>> rLst = new List<List<String>>{};

    // 查询逻辑保留在同步部分
    List<Account> act = [SELECT Id, Name FROM Account LIMIT 5];

    // 调用异步方法处理callout
    performCalloutAsync();

    return rLst;
}

@Future(callout=true)
private static void performCalloutAsync() {
    Http http = new Http();
    String orgDomain = Url.getOrgDomainUrl().toExternalForm();
    String endpoint = orgDomain + '/services/data/v60.0/sobjects/';
    String sessionId = 'Bearer ' + UserInfo.getSessionId();

    HTTPRequest httpReq = new HTTPRequest();
    httpReq.setEndpoint( endpoint );
    httpReq.setMethod( 'GET' );
    httpReq.setHeader( 'Content-Type', 'application/json; charset=UTF-8' );
    httpReq.setHeader( 'Accept', 'application/json' );
    httpReq.setHeader( 'Authorization', sessionId );
    
    HTTPResponse resp = http.send( httpReq );
    
    if ( String.isNotBlank( String.valueOf(resp)) ) {
        System.debug(resp.getHeaderKeys());
        for (String s : resp.getHeaderKeys()) {
            System.debug(resp.getHeader(s));
        }
        System.debug('Response body: ' + resp.getBodyAsBlob().toString());
    }
}

方案2:改用异步自动启动Flow + 定时Apex触发

  1. 创建异步版自动启动Flow:创建Flow时选择“Auto-Launched Flow”,并勾选“Run Asynchronously”,在Flow中调用你的原Invocable方法。
  2. 编写定时Apex类触发该异步Flow:
global class ScheduleAsyncFlow implements Schedulable {
    global void execute(SchedulableContext sc) {
        // 替换为你的Flow API名称
        String flowApiName = 'Your_Async_Flow_API_Name';
        Map<String, Object> flowInputs = new Map<String, Object>();
        // 如需传参,在此添加
        
        Flow.Interview myFlow = Flow.Interview.createInterview(flowApiName, flowInputs);
        myFlow.start();
    }
}

最后通过Setup的“Apex Classes”页面调度该类,替代原时间触发Flow。

注意事项

  • 异步方法(@Future/Queueable)无法直接返回结果给Flow,若需将callout结果回写到Salesforce记录,需在异步方法中直接处理DML。
  • 务必确保异步方法的callout=true参数已正确添加,否则仍会触发callout错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 19:19:58