Managing transactions in Salesforce Apex involves controlling and managing database processes within a single transaction to ensure data accuracy and consistency. In Salesforce, a transaction (or execution context) is a set of actions that are executed as one unit. Either they all work or they all fail (are rolled back). In this post, we will see how to manage transactions in Salesforce Apex.
Table of Contents
- Why Transactions Are Important in Apex
- Ways to Manage Transactions in Salesforce Apex
- 1. Implicit Transaction Management (Default Behavior)
- 2. Manage Transactions Using Savepoints and Rollbacks
- 3. Manage Transactions using Database Methods with Partial Success
- 4. Manage Transactions Using Try-Catch Blocks
- 5. Manage Transactions Using Batch Apex for Large Transactions
- 6. Manage Transactions using Queueable Apex
- Benefits of Transaction Management
- Summary
Why Transactions Are Important in Apex
- Data Integrity: Transactions ensure that database operations (like inserts, updates, or deletes) are completed successfully as a unit. If any operation fails, the entire transaction is rolled back. It will prevent partial inserts/updates that could lead to inconsistent data.
- Governor Limits: Salesforce imposes strict governor limits on DML statements and SOQL queries. Proper transaction management helps optimize resource usage and avoid hitting these limits.
- Error Handling: Transaction management allows developers to handle errors gracefully. We can roll back changes if an exception occurs, ensuring the database remains in a consistent state.
- Atomicity: Transactions ensure that all operations succeed or none are applied, adhering to the ACID (Atomicity, Consistency, Isolation, Durability) principles.
- Performance Optimization: Efficient transaction management minimizes database operations, reducing execution time and resource consumption.
Ways to Manage Transactions in Salesforce Apex
Transaction management ensures database operations are executed reliably, maintaining data integrity and consistency. Below are the primary ways to manage transactions in Apex:
1. Implicit Transaction Management (Default Behavior)
Implicit transaction management is the platform’s automatic handling of transactions. No explicit savepoints or rollbacks are needed for implicit transaction management. Below are the key points for this transaction management
- Apex automatically manages transactions for each execution context (e.g., trigger, Visualforce controller, batch job, or API call).
- A transaction begins when the Apex request starts and ends when it completes or encounters an unhandled exception.
- If an unhandled exception occurs, Salesforce automatically rolls back all database operations in the transaction.
- If any DML operation fails (due to validation rules, triggers, or other errors), the entire transaction is rolled back.
- As it is counted as a single transaction, all DML operations in the transaction count toward governor limits (e.g., 150 DML statements per transaction).
Example:
We have a scenario where the patient and their address will be saved on button click. Patient is handled using the Account object, and a custom object, Address__c, is used to store the patient’s address.
Address object has a validation rule for only US addresses. If another country code is added, then an exception is thrown, and the transaction will roll back.
2. Manage Transactions Using Savepoints and Rollbacks
In implicit transaction management, either all DML statements are successful or all are rolled back. In some situations, a partial save is also required. Using savepoints and rollback, we can implement partial transaction save. Below are key points.
- Savepoints and Rollbacks are used to manage transactions explicitly, allowing developers to set a point in a transaction to which they can revert if an error occurs.
- The Database.setSavepoint() method creates a savepoint, and Database.rollback(savepoint) reverts the database to that point.
- It is ideal for scenarios where you need to undo specific operations while keeping earlier changes intact or for complex logic requiring partial rollbacks.
Code Example:
We need to create order for an online e-commerce platform. It will create orders, process payments, handle inventory, send email notifications, and deliver products. Order and processing payment are mandatory; other actions can be handled later also.
3. Manage Transactions using Database Methods with Partial Success
The implicit transaction method will save all data, or nothing will be saved. The second approach will save partial data based on savepoints. Database methods will save all successful records and roll back only for error records. Key points for saving records using this approach
- Apex provides Database class methods (e.g., Database.insert, Database.update, Database.delete) that offer fine-grained control over DML operations.
- Setting the allOrNone parameter to false allows partial success, where valid records are committed even if some fail.
- This approach is useful for bulk operations where you want to process as many records as possible, even if some fail.
Code Example with the Same Use Case
4. Manage Transactions Using Try-Catch Blocks
Try-catch blocks are essential for Salesforce Apex transaction management. It allows developers to handle exceptions gracefully and control the behavior of transactions when errors occur.
- By catching exceptions, developer can decide whether to roll back a transaction, log errors, or take alternative actions, ensuring data integrity and robust error handling.
- It can be combined with savepoints and database methods or normal DML operations.
- Try-catch blocks provide fine-grained control over transactions, especially in complex scenarios like the e-commerce order processing example we previously referenced in the second method.
- Use specific exception types (e.g., DmlException, QueryException) for precise handling, rather than the generic Exception class, to differentiate between error types.
- Always log errors in the catch block for debugging and auditing, especially in production environments.
- Be careful of DML and SOQL limits within try-catch blocks, as each operation counts toward the 150 DML statements or 100 SOQL query limits.
Code Example with the Same Use Case
Refer to the post Exception Logging in Custom Object : Salesforce Apex for handling exceptions.
5. Manage Transactions Using Batch Apex for Large Transactions
Batch Apex is used to process large records in smaller chunks, each treated as a separate transaction. So if an error occurred in one batch, the job would continue to handle other records. This will help in processing large volumes of records while staying within governor limits.
Code Example
We need to update the email field for all account records if it is empty. As records can be huge, we will use batch Apex to handle this scenario.
6. Manage Transactions using Queueable Apex
Queueable Apex is used to handle asynchronous transactions, allowing long-running or resource-intensive operations to run in the background. This will help in avoiding governor limits in synchronous contexts.
Queueable Apex is ideal for tasks like processing large datasets, making external callouts, or chaining operations that don’t require immediate user interaction. Queueable Apex runs in a separate transaction from the initiating context, providing more governor limits (e.g., 200 SOQL queries, 150 DML statements) compared to synchronous Apex.
Refer to the post Avoid Batch Apex and Use Queueable Class for sample code.
Benefits of Transaction Management
- Data Integrity: It ensures that database operations are completed as a single unit of work, adhering to the ACID principles. If any operation fails, the transaction can be rolled back to prevent partial or inconsistent data.
- Error Recovery: It will allow developers to catch and handle exceptions, enabling recovery actions like rollbacks, logging, or alternative processing. This will prevent unhandled exceptions from disrupting the system.
- Flexibility: Partial success with Database methods supports bulk processing without all-or-nothing constraints. It improves robustness for bulk data processing.
- Improved Performance: Transaction management optimizes database operations by grouping related DML operations and minimizing unnecessary commits or rollbacks, reducing execution time and resource usage.
- Enhanced User Experience: Custom error handling within transactions allows developers to provide meaningful error messages to users, improving usability and trust in the system.
- Auditability and Debugging: Transaction management facilitates logging of errors and transaction outcomes, making it easier to debug issues and audit system behavior.
Summary
Transaction management in Apex provides significant benefits, including data integrity, robust error handling, partial success and rollback capabilities, governor limit compliance, performance optimization, and improved user experience. By using Savepoints, Database methods, and proper exception handling, developers can ensure reliable and efficient database operations.
Need an Expert to Implement Transactions in Apex
Check out our gig for the development of Lightning Web Components, Apex, or Integration.
Related Posts
- Best Practices to Avoid Hardcoding in Apex for Cleaner Salesforce Code
- Best Code Analysis Tools For Salesforce Development
- How to Correctly Publish Platform Event Using Salesforce Apex
- Handle Heap Size for Apex Code Optimization
- Build Scalable Solutions with Salesforce
- Enhance Apex Performance with Platform Caching
- Apex Trigger Code Optimization
- Optimizing Salesforce Apex Code
- Top 10 PMD Issues Salesforce Developers Should Focus on in Apex