Missing controls in transactions
Why is this an issue?
When performing multiple DML operations in sequence, a failure partway through can leave the database in an inconsistent state. For example, if you insert a parent record and then fail while inserting children, you end up with an orphaned parent.
Savepoints allow you to rollback to a known good state if an error occurs.
Examples
Example of incorrect code:
public void createOrderWithItems(Order ord, List<OrderItem> items) {
insert ord;
// If this fails, the Order exists without items
insert items;
}
Example of correct code:
public void createOrderWithItems(Order ord, List<OrderItem> items) {
Savepoint sp = Database.setSavepoint();
try {
insert ord;
for (OrderItem item : items) {
item.OrderId = ord.Id;
}
insert items;
} catch (Exception e) {
Database.rollback(sp);
throw e;
}
}
How can I fix violations?
Create a savepoint: Call
Database.setSavepoint()before the first DML operation.Use try-catch: Wrap DML operations in a try-catch block.
Rollback on failure: Call
Database.rollback(savepoint)in the catch block.Re-throw the exception: After rollback, re-throw or handle the exception appropriately.
When should I disable this rule?
You may dismiss specific violations when:
Each DML operation is independent and partial completion is acceptable
The operations are already wrapped in a higher-level transaction control
Resources
