Dominando las Transacciones en Salesforce: Guía de Savepoints y Rollbacks en Apex
En el desarrollo de Salesforce, la integridad de los datos es fundamental. Aprende a utilizar Database.setSavepoint() y Database.rollback() para asegurar que tu base de datos permanezca consistente.

En el mundo del desarrollo de Salesforce, la integridad de los datos es primordial. Cuando la ejecución de una lógica de negocio compleja implica múltiples operaciones DML (Lenguaje de Manipulación de Datos), asegurar que tu base de datos permanezca en un estado consistente es crítico.
Imagina un escenario donde tu código debe realizar dos acciones: crear un nuevo Pedido (Order) y actualizar el conteo de Inventario. ¿Qué sucede si el Pedido se crea con éxito, pero la actualización del Inventario falla? Sin una gestión de transacciones adecuada, terminas con un Pedido de un artículo que estrictamente no existe en tu sistema.
Aquí es donde entran en juego los Savepoints y Rollbacks de Base de Datos.
Entendiendo el Concepto
Por defecto, las transacciones en Apex son "todo o nada" a un alto nivel. Sin embargo, cuando manejas bloques try-catch complejos o encadenas múltiples procesos, a menudo necesitas un control más fino. Necesitas un botón de "Deshacer" personalizado.
Database.setSavepoint(): Este método marca un punto específico en la línea de tiempo de tu transacción. Es como tomar una instantánea del estado de la base de datos en ese momento exacto.Database.rollback(savepoint): Este método revierte la base de datos al estado en el que estaba cuando se estableció el Savepoint específico.
Escenario del Mundo Real: El Motor de Procesamiento de Pedidos
Alejémonos de los ejemplos genéricos de "Cuenta y Contacto" y miremos un escenario crítico para el negocio.
El Requisito: Necesitamos un método que acepte una lista de Productos para comprar. Para cada producto, el sistema debe:
- Crear un registro
Order_Line_Item__c. - Deducir la cantidad del inventario de
Product2.
La Restricción: Si cualquier parte de este proceso falla (por ejemplo, inventario insuficiente para el 5to artículo en la lista), no se debe insertar ninguna línea de pedido, y ninguno de los conteos de inventario debe cambiar. Toda la transacción debe ser atómica.
El Mal Enfoque (Sin Rollback)
Si simplemente envuelves tu DML en un bloque try-catch sin un rollback, los registros insertados antes de que ocurra el error podrían persistir dependiendo del contexto de tu transacción, dejando tus datos corruptos.
El Buen Enfoque (Usando Savepoints)
Aquí te mostramos cómo implementar una solución robusta usando Database.setSavepoint() y Database.rollback().
public class OrderService {
public static void processOrder(Id orderId, Map<Id, Integer> productQuantities) {
// 1. Definir el Savepoint ANTES de comenzar los cambios en la base de datos
System.Savepoint sp = Database.setSavepoint();
try {
List<Order_Line_Item__c> linesToInsert = new List<Order_Line_Item__c>();
List<Product2> productsToUpdate = new List<Product2>();
// Consultar inventario actual
Map<Id, Product2> productMap = new Map<Id, Product2>(
[SELECT Id, Name, Quantity_In_Stock__c FROM Product2 WHERE Id IN :productQuantities.keySet()]
);
for (Id prodId : productQuantities.keySet()) {
Product2 prod = productMap.get(prodId);
Integer qtyRequested = productQuantities.get(prodId);
// Validación de Lógica de Negocio
if (prod.Quantity_In_Stock__c < qtyRequested) {
// Esto lanza una excepción personalizada pausando efectivamente la ejecución
throw new OrderException('Inventario insuficiente para el producto: ' + prod.Name);
}
// Preparar Línea de Pedido
linesToInsert.add(new Order_Line_Item__c(
Order__c = orderId,
Product__c = prodId,
Quantity__c = qtyRequested
));
// Deducir Inventario
prod.Quantity_In_Stock__c -= qtyRequested;
productsToUpdate.add(prod);
}
// 2. Realizar Operaciones DML
insert linesToInsert;
update productsToUpdate;
System.debug('Pedido procesado con éxito.');
} catch (Exception e) {
// 3. ¡Algo salió mal! Revertir a la instantánea.
Database.rollback(sp);
System.debug('Transacción revertida debido a error: ' + e.getMessage());
// Opcionalmente: Registrar el error en un objeto personalizado o volver a lanzarlo a la UI
throw e;
}
}
public class OrderException extends Exception {}
}
Consideraciones Clave y Mejores Prácticas
Aunque los Savepoints son poderosos, hay comportamientos específicos en Apex que debes conocer:
1. Las Variables Estáticas NO se Revierten
Esta es una pregunta común de entrevista y una fuente de errores complicada. Si modificas una variable estática (por ejemplo, public static Boolean isTriggerExecuted) después de establecer un savepoint, y luego haces rollback, la variable estática retiene su valor modificado.
Si tu lógica depende de banderas estáticas para controlar la recursión de triggers, debes restablecerlas manualmente dentro de tu bloque catch.
2. Brechas de ID
Cuando insertas un registro y luego haces rollback, la base de datos efectivamente "borra" el registro. Sin embargo, el generador de ID de Salesforce no se reinicia. Si insertas una Cuenta con ID terminando en 001 y haces rollback, la siguiente Cuenta que insertes probablemente terminará en 002. El ID 001 se pierde para siempre. Este es un comportamiento normal pero bueno de saber para auditoría.
3. Múltiples Savepoints
Puedes establecer múltiples savepoints (por ejemplo, sp1, sp2).
- Si haces rollback a
sp1, cualquier savepoint establecido después desp1(comosp2) se vuelve inválido. - No puedes saltar de un lado a otro arbitrariamente; es una línea de tiempo lineal.
Conclusión
Usar Database.setSavepoint() y Database.rollback() es el sello distintivo de un desarrollador Apex senior. Asegura que tu aplicación maneje fallos con gracia, manteniendo una estricta integridad de datos incluso cuando procesos complejos de múltiples objetos encuentran errores inesperados.
La próxima vez que escribas una clase de servicio que involucre múltiples sentencias DML, pregúntate: "¿Si la última línea falla, siguen siendo válidos los datos en la primera línea?" Si la respuesta es no, es hora de usar un Savepoint.
Sobre el Autor
Soy Guillermo Miranda, consultor Salesforce especializado en definir y desarrollar soluciones escalables para empresas.
¿Necesitas ayuda con Salesforce?

Ayudo a empresas a diseñar y construir soluciones Salesforce escalables.