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触发
- 创建异步版自动启动Flow:创建Flow时选择“Auto-Launched Flow”,并勾选“Run Asynchronously”,在Flow中调用你的原Invocable方法。
- 编写定时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
相关产品推荐
相关产品推荐

