Using locks in NoSQL database

Locks in NoSQL database

In this article, we explore Read-Modify-Write (RMW) lock which is equivalent to SELECT FOR UPDATE lock often found in RDBMS.

Commonly, NoSQL databases often do not use locking as in traditional RDBMS. But Oracle NoSQL database offers a set of advanced features that can be used to implement locking semantics.

Read-Modify-Write Lock

An RMW lock uses following simple API
  
    RMWLock.update(KVStore store, PrimaryKey pk, Updater updater);
where
  • store is a database connection
  • pk is the primary key of row being locked for update
  • updater is a function that updates the row values pointed by pk
The Updater is a functional interface where the application can implement custom update behavior.
  
    public interface Updater {
       void update(Row row);
    }

It is noteworthy that RMWLock may attempt to update the row more than once. This can happen if another thread is updating the row at the same time. In such cases, RMWLock would invoke the updater function on every retry with the latest state of the updated row.


An use case for RMWLock

Let us consider a typical use case for an RMW lock. Let us create a named, persistent sequence that generates monotonic integral values. A sequence is represented by a name and integer value in a database table.
A client, say A, locks the database row and increments the value exclusively by an amount L. If another thread B simultaneously attempts to do the same, the other thread B will block.
Once client A had updated the value from x to x+L, then only thread B will see the updated value x+L and then B can update the value again to a different value, say x+L+L.

A typical usage of RMW lock in this simple case would be:
        
          new RMWClient().update(store, pk, new Updater() {
              @Override
              public void update(Row row) {
                 int lastUpdatedValue = row.get("NEXT_VALUE").asInt().get();
                 row.put("NEXT_VALUE", lastUpdatedValue&nbsp+ 20);
              }
           };
Here we use the updater function to increment NEXT_VALUE by 20. The RMWLock ensures that NEXT_VALUE is updated atomically and without any other thread updating at the same time.

Resources

The code for RMWLock is available here. This code can directly be used in an application.
A more complete example of RMWLock to realize a persistent sequence is described in a separate blog.

New trillion