💃 A game-changer coming to Apex 🕺

We're stoked about this Salesforce '24 Release feature

Good morning, Salesforce Nerds!

There’s a new toy coming soon for Salesforce Developers that need to process large datasets! 🥳 

I don’t know about you, but I’m excited to get my hands on it and try it out.

As part of the Summer ‘24 release, Salesforce is releasing a Beta version of Apex Cursors!

Giving architects & developers a great alternative to Batch Apex! 🤙 

DevOps Summit: Developing a long-term Salesforce DevOps mindset

Register now for the Virtual DevOps Summit

This year at the DevOps Summit, get your workload under control with DevOps best practices. You’ll hear real-world insights about the DevOps strategies and tooling that can accelerate your delivery, and drive sustainable growth for your organisation.

Listen to experts, Jonny Harris (Zurich) and Sami Hawkins (West Shore Home) as they share insights into how their teams leveraged DevOps best practices to meet growing demand.

If you’re looking for scalable ways to develop on Salesforce, join us.

TABLE OF CONTENTS

DRUM ROLL PLEASE

INTRODUCING APEX CURSORS

Apex cursors let you break up the processing of a SOQL query result into smaller pieces. 🧩 

These separate pieces can then be processed within the bounds of a single transaction.

These give you with the ability to work with large query result sets, without actually returning the entire result set. 🔥 

With cursors you can:

Traverse a query result in parts

Navigate both forward and backward in the result set

If you work with high-volume and high-resource processing jobs - these bad boys can help you out!

What’s cool is that these are a great alternative to batch Apex. They even address some of batch Apex’s limitations.

Cursors are also super powerful because they can be used in a chain of queueable Apex jobs. ⛓️ 

WHAT’S THE BIG DEAL

HOW DO THEY HELP?

In a word?

Performance! 🚀 

An Apex cursor will boost performance by let you process query results in increments.

So, instead of getting all the records you just get a subset. Do your thing. Then move on to the next subset you need to work with. 🔥 

This gives you some benefits:

Memory management - don’t load the entire dataset. It strains the system. Get a smaller piece of it to work with.

Navigation - you can move forward AND backward through the returned dataset. Super flexible.

Transactions - a cursor operates within the bounds of a single transaction.

WHAT’S NEXT

ALL THE THINGS!

To use an Apex cursor here’s what you’ll need to do:

👉️ Create the cursor - run a SOQL query with Database.getCursor() or Database.getCursorWithBinds() and a cursor will be spawned representing the dataset.

👉️ Fetch records from the cursor - use the fetch() method to get a specified number of records from a the cursor. It takes two integers as arguments - a position within the cursor to start returning data and a count for how many rows to return.

As with anything Salesforce there are limits. Let’s check them out:

Max # of rows per cursor: 50 million (both synchronous and asynchronous)

Max # of fetch calls per transaction: 10 (both synchronous and asynchronous)

Max # of cursors per day: 10,000 (both synchronous and asynchronous)

Max # of rows per day (aggregate limit): 100 million

EXAMPLE TIME

SHOW ME THE CODE!

public class QueryChunkingQueuable implements Queueable {
    private Database.Cursor locator;
    private integer position;

    public QueryChunkingQueuable() {
        locator = Database.getCursor
                  ('SELECT Id FROM Contact WHERE LastActivityDate = LAST_N_DAYS:400');
        position = 0;
    }

    public void execute(QueueableContext ctx) {
        List<Contact> scope = locator.fetch(position, 200);
        position += scope.size();

        // PROCESS THE DATA HERE

        if(position < locator.getNumRecords() ) {
            // process the next chunk
            System.enqueueJob(this);
        }
    }
}

Here we instantiate a Cursor by executing a SOQL statement that will return the Id’s of each Contact with the LastActivityDate within the past 400 days.

Then when we’re in the execute() method we just fetch the next 200 rows from the cursor.

Run our undoubtedly superb business logic.

Since we’re keeping track of the position, we can check if there are more rows in need processing. If so, queue the job up.

SOUL FOOD

Today’s Principle

"The best preparation for tomorrow is doing your best today.”

H. Jackson Brown, Jr.

and now....Salesforce Memes

What did you think about today's newsletter?

Login or Subscribe to participate in polls.