我构建了一个 @InvocableMethod,用作 Salesforce Flow 中的操作。它的基本功能是查找一些记录,将结果保存在 sObject 列表中,然后调用并处理结果。当我将操作添加到流程并单击调试按钮来运行它时,我收到“System.CalloutException:您有未提交的工作待处理。请在调用之前提交或回滚”错误。
但即使将 Database.setSavepoint()、Database.rollback() 和 Database.releaseSavepoint() 添加到可调用方法的代码中,流程仍然会生成相同的错误。
但是,在流程外部运行可调用方法的代码(例如通过执行匿名),代码运行良好。
请注意
这是一些演示该问题的代码。当匿名运行时,它将正常执行。通过 Salesforce Flow 运行时,会生成上述错误。
@InvocableMethod(label='Test Database Rollback with Callout in a Flow' callout=true)
global static List<List<String>> testDatabaseRollback() {
Savepoint sp = Database.setSavepoint();
List<List<String>> rLst = new List<List<String>>{};
List<Account> act = [SELECT Id, Name FROM Account LIMIT 5];
Database.rollback(sp);
Database.releaseSavepoint(sp);
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());
}
return rLst;
}
我明白了这个问题是什么。基本上,错误消息与问题无关......
我的流程是计划触发流程。我找到了有关计划触发流程注意事项的文档:https://help.salesforce.com/s/articleView?id=sf.flow_considerations_trigger_schedule.htm
其中指出: “计划触发的流只能在执行 Wait 元素后进行标注。例如,如果没有 Wait 元素,流将无法访问外部对象、执行进行标注的 Apex 操作或执行从外部服务注册生成的操作.”
一旦我添加了等待,它就起作用了。