have uncommitted work pending. Please commit or rollback before calling out

匿名 (未验证) 提交于 2019-12-03 01:00:01

问题:

i have a batch class

 public class BatchCreateGCalendars implements Database.Batchable<SObject>, Database.Stateful, Database.AllowsCallouts {          private String query;         private String pageToken ;         private String accessToken;         private String CalendarId;          public BatchCreateGCalendars(){              this.query = 'Select Id, Name, CalendarId__c from CalendarSettings__c'; // Query to get the CalendardID (Google ID)          }          public Database.Querylocator start(Database.BatchableContext BC){              return Database.getQueryLocator(query);          }          public void execute(Database.BatchableContext BC, List<sObject> scope){              GoogleForce__c gApp           = GoogleForce__c.getAll().values()[0];                     GCalendarUtil.Calendar cal    = new GCalendarUtil.Calendar();             GCalendarUtil.GResponse gResp = new GCalendarUtil.GResponse();                 String endPoint = GCalendarUtil.CALENDAR_BASE + GCalendarUtil.CAL_URL; // Calendar Endpoint              // Iterate over the records, delete each calendar and create the calendar again.              for(CalendarSettings__c c : (List<CalendarSettings__c>)scope){                    String delEndpoint = endpoint + '/' + c.CalendarId__c;                  if(gApp.ExpiresIn__c < system.now()){                     gResp               = GCalendarUtil.getNewToken(gApp);                     accessToken         = gResp.access_token;                     gApp.AccessToken__c = gResp.access_token;                     gApp.ExpiresIn__c   = System.now().addSeconds(gResp.expires_in);                  }else{                     accessToken = gApp.AccessToken__c;                     System.debug('Calendar Id  is '+ c.CalendarId__c);                 }               String re=  GCalendarUtil.doApiCall(null,'GET','https://www.googleapis.com/calendar/v3/calendars/'+c.CalendarId__c+'/events',accessToken);              re = re.replaceAll('"end":','"end1":');     re = re.replaceAll('"dateTime":','"dateTime1":');                 System.debug('response is' +re);                JSON2Apex1 aa = JSON2Apex1.parse(re);                 List<JSON2Apex1.Items> ii = aa.items ;                         System.debug('next token is'+ aa.nextPageToken);                List<String> event_id =new List<String>();                if(ii!= null){                for(JSON2Apex1.Items i: ii){                event_id.add(i.id);                }                }            for(String s:event_id)            {GCalendarUtil.doApiCall(null,'DELETE','https://www.googleapis.com/calendar/v3/calendars/'+c.CalendarId__c+'/events/'+s,accessToken);             }        pageToken = aa.nextPageToken;        CalendarId=c.CalendarId__c;                 if(pageToken!=null)                deleteEvents(accessToken , pageToken,c.CalendarId__c);              }              update gApp;         }          /*             After the batch job is finished, trigger the other batch jobs where the Campaigns are sent as Events to the calendars.              Use the CalendarQuery field on the each calendarSettings record.         */          public void finish(Database.BatchableContext BC){             BatchDeleteEvents bjob1 = new BatchDeleteEvents(CalendarId,accessToken);                 Database.executeBatch(bjob1,9);                for(CalendarSettings__c c  : [Select Id, Name, CalendarQuery__c, CalendarId__c,FieldToDisplay__c from CalendarSettings__c WHERE Name IN ('Public Calendar', 'Internal marketing Calendar')]){                  BatchPublicCampaignsToGoogle bjob = new BatchPublicCampaignsToGoogle(c.CalendarQuery__c,c.CalendarId__c,c.FieldToDisplay__c);                 Database.executeBatch(bjob,9); // This is set to process 9 records, allowing 1 extra callout for refresh token in case needed.              }           }          public static void deleteEvents(String accessToken,String pageToken,String CalendarId){          List<Event__c> event_id =new List<Event__c>();          while(pageToken != null)     {   String re = GCalendarUtil.doApiCall(null,'GET','https://www.googleapis.com/calendar/v3/calendars/'+CalendarId+'/events?pageToken='+pageToken,accessToken);                     System.debug('next page response is'+ re);                      re = re.replaceAll('"end":','"end1":');     re = re.replaceAll('"dateTime":','"dateTime1":');         JSON2Apex1 aa = JSON2Apex1.parse(re);        List<JSON2Apex1.Items> ii = aa.items ;       System.debug('size of ii'+ii.size());       pageToken = aa.nextPageToken ;                 if(ii!= null){                for(JSON2Apex1.Items i: ii){                event_id.add(new Event__c(name = i.id));                }                }         }         insert event_id;           }      } 

in this code i am getting error at this line

String re=  GCalendarUtil.doApiCall(null,'GET','https://www.googleapis.com/calendar/v3/calendars/'+c.CalendarId__c+'/events',accessToken); 

error is

You have uncommitted work pending. Please commit or rollback before calling out 

why i am facing this error please help and one more doubt is when i call this code in finish method

 BatchDeleteEvents bjob1 = new BatchDeleteEvents(CalendarId,accessToken);                     Database.executeBatch(bjob1,9);  

it will execute this code synchronously na means all objects in batch of 9 processed and then control will come on this code

BatchPublicCampaignsToGoogle bjob = new BatchPublicCampaignsToGoogle(c.CalendarQuery__c,c.CalendarId__c,c.FieldToDisplay__c);                     Database.executeBatch(bjob,9); 

回答1:

you can't make Callouts in Salesforce/Apex along with DML statements.

You could first perform CallOut based on the Callout Status you can invoke DML Statments.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!