DML can be perform in two ways in Apex – Using DML statements or Database class methods.
Usinig DML Statements – to insert new record
//Create the List of sObject to insert
List accList = new List();
accList.add(new Account(Name='TestAcc1'));
accList.add(new Account(Name='TestAcc3'));
accList.add(new Account(Name='TestAcc3'));
// DML Statement
insert accList;
Using Database class – to insert record
//Create the List of sObject to insert
List accList = new List();
accList.add(new Account(Name='TestAcc1'));
accList.add(new Account(Name='TestAcc3'));
// DML Statement
Database.SaveResult[] srList = Database.insert(accList, false);
//Iterate through each returned result
for(Database.SaveResult sr : srList) {
if(sr.isSuccess()) {
// Operation was successful, so get the ID of the record that was processed
System.debug('Successfully inserted account. Account ID: ' + sr.getId());
}
else {
// Operation failed, so get all errors
for(Database.Error err : sr.getErrors()) {
System.debug('The following error has occurred.');
System.debug(err.getStatusCode() + ': ' + err.getMessage());
System.debug('Account fields that affected this error: ' + err.getFields());
}
}
}
Database Methods :- Apex Database class provides methods that perform DML operations. These Database methods are static and are called using class name(Database).
- Database.insert()
- Database.update()
- Database.delete()
- Database.upsert()
- Database.merge()
- Database.undelete()
Using Database class method , you have an option allOrNone which specify whether to allow for partial record processing if errors are encountered.You can do so by passing an additional second Boolean parameter.
If you specify false for this parameter and if a record fails, the remainder of DML operations can still succeed. This wont throw any exception, instead return a result object array containing the status of each operation and any error occur.
By default this optional parameter is true – means that if at least one sObject failed to processed then all sObject can’t processed
Insert and Update operation return an array of Database.saveResult object.
Database.saveResult[] results = Database.insert(recordList, false);
NOTE- Upsert return Database.upsertResult object and delete returns Database.deleteResult object.
When to use DML Statement or Database class methods :-
Use DML statements if you want any error that occurs during bulk DML processing to be thrown as an Apex exception that immediately interrupts control flow (by using try. . .catch blocks). This behavior is similar to the way exceptions are handled in most database procedural languages.
Use Database class methods if you want to allow partial success of a bulk DML operation—if a record fails, the remainder of the DML operation can still succeed. Your application can then inspect the rejected records and possibly retry the operation. When using this form, you can write code that never throws DML exception errors. Instead, your code can use the appropriate results array to judge success or failure. Note that Database methods also include a syntax that supports thrown exceptions, similar to DML statements.
Single Vs. Bulk DML :-
DML operations can performed on single sObject or in bulk on a list of sObjects. Performing bulk DML operations is the recommended way because it helps avoid hitting governor limits, such as the DML limit of 150 statements per Apex transaction.
Requirement :- Updating all Contacts Description__c field to a new value if the department field matches a certain value.
Wrong approach :-
for(Contact badCon : conList) {
if (badCon.Department = 'Finance') {
badCon.Description__c = 'New description';
}
// Not a good practice since governor limits might be hit.
update badCon;
}
You are looping through all contact and the contact whose department matches to the value, you are updating the contact. The problem here is -If the number of contact with matching criteria is more then 150, the next update throw exception that can’t be caught for exceeding the DML statement limit of 150.
Recommended Approach :- Bulkify DML
// List to hold the new contacts to update.
List updatedList = new List();
for(Contact con : conList) {
if (con.Department == 'Finance') {
con.Description = 'New description';
// Add updated contact sObject to the list.
updatedList.add(con);
}
}
// Call update on the list of contacts.
// This results in one DML call for the entire list.
update updatedList;
Here you are bulkifies the DML by calling update on a list of contacts and this is only one DML, below the limit 150 DML.
The other governor limit that affects DML operations is the total number of 10,000 rows that can be processed by DML operations in a single transaction.
DML Transaction:- DML operations execute within a transaction. All DML operations in a transaction either complete successfully, or if an error occurs in one operation, the entire transaction is rolled back and no data is committed to the database.
For example, if a trigger or class creates two accounts and updates one contact, and the contact update fails because of a validation rule failure, the entire transaction rolls back and none of the accounts are persisted in Salesforce.
Share this article with friends: