Skip to main content

Fire Platform Events from Batch Apex

Fire Platform Events from Batch Apex using Database.RaisesPlatformEvents Interface

With Summer'19 release (API version 44 or later), now it is possible to fire platform events from batch apex. So whenever any error or exception occurs, you can fire platform events which can be handled by different subscriber.

Batch class needs to implement "Database.RaisesPlatformEvents" interface in order to fire platform event.

global class SK_AccountProcessBatch implements Database.Batchable<sObject>,Database.RaisesPlatformEvents{
   //batch logic
}

To understand more about platform events please refer below links

Platform Events : Way to Deliver Custom Notifications within Salesforce or to external Application

Here I will be writing simple batch class which process account records and if any errors occurs during update, then all account record Ids will be published using platform event.

I have created platform event with below mentioned fields:


Below is batch apex code which will fire platform event and I wrote a trigger which will subscribe to platform event.

global class SK_AccountProcessBatch implements Database.Batchable<sObject>,Database.Stateful,Database.RaisesPlatformEvents{
global List<string> errorRecordsId=new List<String>();
global Database.QueryLocator start(Database.BatchableContext BC){
return Database.getQueryLocator('Select id,name,Type,rating,industry from Account Limit 1000');
}
global void execute(Database.BatchableContext BC, List<sObject> scope){
List<Account> accountListForUpdate = new List<Account>();
for(sobject s : scope){
Account acc =(Account)s;
if(acc.Type!=null){
if(acc.Type.equalsIgnoreCase('Customer - Direct'))
s.put('Rating','Hot');
accountListForUpdate.add(acc);
}
}
if(accountListForUpdate.size()>0){
Database.SaveResult[] srList = database.update(accountListForUpdate,false);
// Inspect publishing result
integer recordIndex=0;
// Iterate through each returned result
for (Database.SaveResult sr : srList) {
if (!sr.isSuccess()) {
for(Database.Error err : sr.getErrors()) {
System.debug('The following error has occurred.'+err.getStatusCode() + ': ' + err.getMessage());
errorRecordsId.add(accountListForUpdate[recordIndex].id);
}
}
recordIndex++;
}
}
}
global void finish(Database.BatchableContext BC){
system.debug('*****failed recordIds:'+string.join(errorRecordsId,','));
// Create an instance of the Demo event
Demo_Event__e demoEvent = new Demo_Event__e(
Event_Info__c='Account records failed during SK_AccountProcessBatch processing',
Is_Event_Valid__c=true,
Event_Publisher__c='SK_AccountProcessBatch',
Records_Ids__c=string.join(errorRecordsId,','));
// Call method to publish events
Database.SaveResult sr = EventBus.publish(demoEvent);
// Inspect publishing result
if (sr.isSuccess()) {
System.debug('Successfully published event.');
} else {
for(Database.Error err : sr.getErrors()) {
System.debug('Error returned: ' + err.getStatusCode() +' - ' + err.getMessage());
}
}
}
}
trigger DemoEventTrigger on Demo_Event__e (after insert) {
for (Demo_Event__e event: Trigger.New) {
if (event.Is_Event_Valid__c == true) {
//perform logic based on event information
system.debug('**Records_Ids__c passed through platform events:'+event.Records_Ids__c);
}
}
}
I have used Database.Stateful interface to store the record ids which are getting failed in each batch execution. In finish method, I am firing platform event with all failed records Ids.

Below is logs generated by trigger which will get executed whenever platform event is fired.


In order to see debug logs for platform events subscription, add a trace flag entry for the Automated Process entity in Setup. The debug logs aren’t available in the Developer Console’s Log tab.

Navigate to SetUp --> Debug Logs --> New
  • For Traced Entity Type, select Automated Process.
  • Select the time period to collect logs and the debug level.
  • Click Save.
I have also created a lightning component which will subscribe to platform events and will display the event message as shown below in snapshot:

Please refer below link to understand how to use platform events in lightning components:

Handling Platform Events in Lightning Components


Hope this will help!!!

Comments

Popular posts from this blog

How to Build a Basic Salesforce REST API (With Test Class)

How to Build a Basic Salesforce REST API (With Test Class) and Test with POSTMAN Salesforce : Creating Anonymous Apex REST APIs with Force.com The Force.com REST API lets you integration with Force.com applications using standard HTTP methods. This API provides a way to expose the data you have within your Force.com application to external applications – both mobile and non-mobile. A few useful bits of information related to these REST APIs: This sample Code you how to implement a simple REST API to fetch Account in Apex class: @RestResource(urlMapping='/Account/*') global with sharing class MyRestResource { @HttpGet global static Account doGet() { RestRequest req = RestContext.request ; RestResponse res = RestContext.response ; String accountId = req.requestURI. substring ( req.requestURI. lastIndexOf ( '/' ) +1 ) ; Account result = [SELECT Id, Name, Phone, Website FROM Account WHERE Id = : account...

Salesforce UNABLE_TO_LOCK_ROW: unable to obtain exclusive access to this record

Unable to lock row - Record currently unavailable errors Description When a record is being updated or created, we place a lock on that record to prevent another operation from updating the record at the same time and causing inconsistencies on the data. These locks normally last for a few seconds and when the lock is released, other operations can do whatever processing they are supposed to do on the record in question. However, a given transaction can only wait a maximum of 10 seconds for a lock to be released, otherwise it will time out. Resolution What and when records get locked depends on the operation you are performing and the main record you are working on. The  Force.com Record Locking Cheatsheet   provides detailed information on this and it's highly recommended that you familiarize yourself with its contents. Common Scenarios that prevent unlocking record a. Email-To-Case When an email is processed by email-to-case, triggers on the email mes...

Salesforce Callout using Future Method

Hi All, Today's topic , Use of Future method in web services callout. Consider one scenario, Whenever ,We create one Account record or Edit a Account record using UI, Populate Billing city based on Billing Zipcode . Like Below image before save, After Press the save button,Billing city should auto populate. We want to populate Billing city based on Billing zipcode using below API endpoint. Postal PIN Code API Postal PIN Code API allows developers to get details of Post Office by searching Postal PIN Code or Post Office Branch Name of India. It has following format:         1. Get Post Office(s) details search by Postal PIN Code             http://postalpincode.in/api/pincode/{PINCODE}         2.Get Post Office(s) details search by Post Office branch name            http://postalpincode.in...