2013-02-18 17 views
1

之前,我有一個批次類有未提交的待處理工作。請提交或回滾呼叫

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; 


     } 

    } 

在這段代碼我在這行得到錯誤

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

誤差

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

爲什麼我面對這個錯誤請幫助和更多的疑問是當我在完成方法中調用此代碼

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

將同步吶執行此代碼意味着一批9所處理的所有對象,然後控制就會來到這個代碼

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

嗨Ritesh!恐怕我沒有其他答案,比我從http://stackoverflow.com/questions/14545072/unexpected-null-pointer-exception-in-testing發表的評論。你必須重新排列它們。首先標註,然後DML(插入,更新等)。或者DML +'@ future',所以標註出現在不同的上下文中(然後,如果標註失敗,則需要弄清楚如何處理插入的數據)。甚至沒有'Database.setSavepoint()'會幫助你。 – eyescream 2013-02-18 14:48:31

+0

只是仔細看看代碼時,我註釋掉從執行調用deleteEvents函數,然後沒有錯誤,但如此調用deleteEvents函數導致error.but在該函數中,我首先調用callouts然後插入它並執行最後一個語句'更新gApp;'不是DML語句gApp是自定義設置,當我忽略它仍然得到相同的錯誤。什麼是錯誤的deleteEvent函數我首先標註api,然後插入按規則仍然收到錯誤 – 2013-02-18 16:07:42

+0

@eyescream請回復,如果我跟隨規則爲什麼我得到錯誤? – 2013-02-18 16:08:24

回答

0

你不能在Salesforce /頂點標註與DML語句一起。

您可以首先根據標註狀態執行CallOut,然後您可以調用DML統計信息。