Salesforce System.Callout异常:您有未提交的工作挂起。请提交或回滚

Salesforce System.Callout异常:您有未提交的工作挂起。请提交或回滚,salesforce,apex-code,Salesforce,Apex Code,我的CreateTimeLine代码是 public static void createTimeLine(List<sObject> objList,Map<String,String> contentMap){ Map<Id,User> userMap = new Map<Id,User>([Select id,Name From User where Authorize__c = true]); Map<Id,GlassUserApiS

我的CreateTimeLine代码是

public static void createTimeLine(List<sObject> objList,Map<String,String> contentMap){
Map<Id,User> userMap = new Map<Id,User>([Select id,Name From User where Authorize__c = true]);
Map<Id,GlassUserApiSettings__c> userSettingsMap = new Map<Id,GlassUserApiSettings__c>();

for(Id user_id : userMap.keySet()){
GlassUserApiSettings__c userSettings = GlassUserApiSettings__c.getValues(user_id);
if(userSettings == null)
{ User u =userMap.get(user_id);
u.Authorize__c = false;
update u;
}
else userSettingsMap.put(user_id,userSettings);

}
for(sObject obj : objList)
for(Id userId: userSettingsMap.keySet() ){
String type = '';
if(contentMap.get('Object').equals('FeedItem'))
type='Post';
if(contentMap.get('Object').equals('FeedComment'))
type= 'Comment';
GlassUserApiSettings__c userSettings = userSettingsMap.get(userId);
if(((String)obj.get(contentMap.get('Content'))).contains('@'+userMap.get(userId).Name)){
Datetime tokenExpiredTime = userSettings.LastModifiedDate;
tokenExpiredTime.addSeconds(Integer.valueOf(userSettings.ExpireDuration__c));
String body='{"html":"<article><section><div class="text-auto-size">'+type+':'+
'<p class="yellow">"'+obj.getSObject('CreatedBy')+'&nbsp;'+obj.getSObject('CreatedBy')+'</p><p>'+obj.get(contentMap.get('Content'))+'</p>'+
'</div></section> </article>"}';
System.debug('Body is '+body);
/* if(tokenExpiredTime >= System.now()){
GMirror.TokenResponse res = GMirrorUtil.refreshToken(userSettings.RefreshToken__c);
userSettings.RefreshToken__c = res.refresh_token;
userSettings.AccessToken__c = res.access_token;
userSettings.ExpireDuration__c = Integer.valueOf(res.expires_in) ;
update userSettings;
}*/
String timelineRes = doApiCall(body,'POST','https://www.googleapis.com/mirror/v1/timeline',userSettings.AccessToken__c);
GMirror.TimelineResponse createdTimeCard = (GMirror.TimelineResponse) JSON.deserialize(timelineRes,GMirror.TimelineResponse.class);
if(createdTimeCard.id != null)
System.debug('created timeline card :'+createdTimeCard);
else { try{
throw new GMirror.TimelineException(null,timelineRes);
}
catch(Gmirror.TimelineException e){
System.debug(e.getMessage());
}
}
}
}
}

正如您所看到的,在doApiCall函数之后,我没有使用任何DML语句。但是为什么我要面对这个错误呢??请使用指南解决此问题。

您在进行标注之前进行更新-
更新u
更新用户设置。您应该在调出后进行更新。

但实际上,一个有您声誉的人应该先用谷歌搜索这个问题……事实上,我正在测试的testcase没有涵盖这些DML操作,仍然出现错误,这就是为什么我为没有以正确的方式表示歉意。我在得到这个消息后,通过触发器调用batch apex线路误差
public class BatchPublishTimeLine implements Database.Batchable<sObject>{
sObjectIterable iterable;
Map<Id,User> userMap;
Map<String,String> contentmap;

public BatchPublishTimeLine(List<sObject> objectList,Map<String,String> contentmap){
iterable = new sObjectIterable(objectList);
this.userMap = new Map<Id,User>([Select Id,Name From User WHERE Authorize__c = true]);
this.contentmap = contentmap;
}
public Iterable<sObject> start(Database.BatchableContext BC){
return iterable;
}
public void execute(Database.BatchableContext BC, List<sObject> scope){
GMirrorUtil.createTimeLine(scope, contentMap);
}

public void finish(Database.BatchableContext BC){
System.debug('Job Has been Finished');
}
}

public static String doAPICall(String postBody, String method, String endPoint, String accessToken){

HttpRequest req = new HttpRequest();
Http http = new Http();
HttpResponse res;

req.setEndpoint(endPoint);
req.setMethod(method);
req.setHeader('Content-Type','application/json');

if(method == 'POST' || method == 'PUT')
req.setBody(postBody);
req.setHeader('Authorization','Bearer ' + accessToken);
res = http.send(req);
String result = res.getBody();
System.debug('status code is '+res.getStatus());
System.debug('result is'+res.getBody());
return result;
}
String timelineRes = doApiCall(body,'POST','https://www.googleapis.com/mirror/v1/timeline',userSettings.AccessToken__c);