Optimistic locking is the default option when managing concurrent data with ORDA and is implemented through the .save() function when saving a record. Locks are not applied before accessing a record and if there was a conflict it is only checked after the access has been attempted. The .save() function checks the stamp on the record and if it has been changed while it was being used, .save() returns unsuccessful and the programmer needs to decide what happens if these conflicts happen, like trying again or rolling back to the last version of the record. This style of locking is ideal for high volume web applications where conflicts are infrequent or it is difficult for clients to maintain database locks. Here is an example of how trying again after a conflict would be implemented:
C_OBJECT($info) C_BOOLEAN($done) $entity:=ds.Person.all().first() Repeat $entity.data:="updated" $info:=$entity.save() $done:=$info.success If(Not($done)) $entity.reload() End if Until($done) |
Because the optimistic style of locking requires the programmer to handle the conflicts, sometimes pessimistic locking is a better alternative. In scenarios where data consistency is critical, using 4D's entity.lock() and entity.unlock() to implement pessimistic locking might be better.
C_OBJECT($info) $entity:=ds.Person.all().first() $info:=$entity.lock() If ($info.success) $entity.data:="updated" $entity.save() $entity.unlock() End if |
* The above code is taken from 4D Summit 2020 Advanced Training by JPR
This implementation can cause threads to wait for a long time for a record to be unlocked which can affect performance. This implementation also can lead to deadlocks which the programmer will also need to be mindful of if they choose this option.