RimuDB Logo
Database Access Framework for Java

Row Locking

Optimistic Locking

By default, the record locking performed by RimuDB is optimistic. That is, a record is read from the database and held in memory and not until update time is there any consideration of whether or not another process has updated that same record in the database.

There are five strategies that can be chosen for performing optimistic locking in RimuDB:

  • all - In this strategy (the default), when an update is performed, all the columns in the database must match the same values as when the record was first read from the database.
  • dirty - In this strategy, when an update is performed, only the modified columns in the database must match the same values as when the record was first read from the database.
  • version - In this strategy, a special column must be added to the database table. Typically this is an integer or timestamp. When an update is performed, the version column in the database must match the same value as when the record was first read from the database.
  • last-commit-wins - In this strategy, when an update is performed, the current state of the record in the database is not considered. Data can potentially be overwritten with this strategy.
  • read-prior - In this strategy, immediately before an update is performed, the record is re-read from the database and compared to the the original values before the update was performed. This is not a recommended strategy. Data can still potentially be overwritten with this strategy, and it introduces a lot more database overhead.

The optimistic locking strategy is defined for each data object in the compounddatabase.xml configuration file.


<dataobject class="org.rimudb.testdb.OrderAddressDO" group="groupa" />
<dataobject class="org.rimudb.testdb.OrderHeaderDO" group="groupa" optimistic_locking="version"/>
<dataobject class="org.rimudb.testdb.OrderLineDO" group="groupa" optimistic_locking="all"/>
<dataobject class="org.rimudb.testdb.OrderTransactionDO" group="groupa" optimistic_locking="dirty"/>


Pessimistic Locking

Pessimistic locking can also be performed by RimuDB. In this locking strategy a record is locked when it is first read from the database, preventing other processes to update the record until the either the record is updated, deleted, or the lock explicitly released.

Use the Finder.find() method to retrieve a record with a lock.


int orderNr = 5;
int sequence = 2;
OrderLineDO orderline = orderLineFinder.find(orderNr, sequence, Lock.UPDATE);
orderline.setMessage("some new value");
orderline.commit();


With pessimistic locks, your application controls how long the lock is held. When the record is first read and locked, a connection from the pool is held. Only when your application issues the update, delete or release, does the connection get returned to the pool. It is wise to only hold pessimistic locks for a very short period of time and to code defensively so that even if exceptions occur, the lock (and therefore the connection) is released.


int orderNr = 5;
int sequence = 2;
OrderLineDO orderline = null;
try {
   orderline = orderLineFinder.find(orderNr, sequence, Lock.UPDATE);
   orderline.setMessage("some new value");
   orderline.commit();
} catch (Exception e) {
   if (orderline != null) {
      orderline.releaseLock();
   }
}


Pessimistic Locking Options

There are other locks that can be used besides an UPDATE lock. How these values are used depends upon the database.

SQL Server - Lock.DIRTY_READ adds the locking hint 'WITH (nolock)' to the SELECT statement. Lock.UPDATE adds the locking hint 'WITH (updlock, rowlock)'.

Other databases - Only the Lock.NONE and Lock.UPDATE values are used. Lock.UPDATE appends 'FOR UPDATE' to the SELECT statement. Lock.NONE does not add clause.