Record Locking

Apex code has many entry points. Code can be invoked from outside of Force.com via a Web service call, by modifying a record with a trigger on it in the native user interface, inside Force.com IDE in an Execute Anonymous view, or in a unit test. Additionally, multiple users or programs can be running the same code simultaneously or code that uses the same database resources.

DML operations using values returned by SOQL or SOSL queries are at risk for dirty writes. This means values updated by one program have been modified by a second program running at the same time. The changes of the second program are lost because the first program is operating with stale data.

For example, if your code retrieves a record and then modifies its value later in the program, it requires a write lock on the record. A write lock prevents the record from being concurrently updated by another program. Write locks are provided in Apex via the SOQL FOR UPDATE keyword. This keyword indicates to Apex that you intend to modify the records returned by the SOQL query. This locks the records, preventing them from being updated by another program until your transaction is complete. No explicit commit is necessary. The records are unlocked, and changes are automatically committed when the program exits successfully or is rolled back otherwise.


Note

You cannot use the ORDER BY keyword with FOR UPDATE. Query results are automatically ordered by Id field.


Listing 5.20 is an example of record locking in Apex. Tim Barr is given a raise of $20. His Resource record is retrieved and locked, the hourly cost is incremented, and the database is updated. The use of FOR UPDATE ensures that this code running simultaneously in two contexts still results in the correct outcome: a $40 increase in hourly cost rate, $20 from each of the two independent execution contexts, serialized with FOR UPDATE. Without the locking, a dirty write could cause one of the updates to be lost. For this example to execute without errors, make sure you have a Contact record named Tim Barr with a non-null value for the Hourly_Cost_Rate__c field.

Listing 5.20 Record Locking Example


Contact tim = [ SELECT Id, Hourly_Cost_Rate__c
  FROM Contact
  WHERE Name = 'Tim Barr' LIMIT 1
  FOR UPDATE ];
tim.Hourly_Cost_Rate__c += 20;
update tim;


..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.222.3.255