Skip to content

OptimisticConcurrency.md

LambdaZen edited this page Dec 13, 2017 · 2 revisions

Optimistic Concurrency Control

Bitsy implements optimistic concurrency control and does not lock on any vertex or edge when it is queried or updated. Instead, every queried vertex or edge is retrieved along with its version number. When a vertex or edge is modified, the version number is checked before the element is committed. If the version matches the latest version for that vertex/edge in the database, the commit goes through. Otherwise, the Bitsy database throws a BitsyRetryException.

Note: The version numbers are at the vertex and edge level. So if two different properties are updated concurrently by two transactions, one of them will fail with the BitsyRetryException.

Isolation levels

Starting with version 1.1, Bitsy offers two isolation levels, viz. REPEATABLE_READ and READ_COMMITTED. In the REPEATABLE_READ isolation level, all vertices and edge objects with the same ID are guaranteed to be the same objects. Furthermore, a vertex/edge accessed within a transaction once is guaranteed to return the same properties throughout the remainder of the transaction.

In the READ_COMMITTED mode, vertex/edge queries return different objects each time with the latest committed information from the database. This mode consumes less memory in the transaction context and is preferred for transactions that perform large queries.

The default transaction isolation level is REPEATABLE_READ. You can adjust the settings using these the following methods available in BitsyGraph:

  • getDefaultIsolationLevel(), setDefaultIsolationLevel(BitsyIsolationevel): These methods get/set the default isolation level for all future transactions, excluding the current one.

  • getTxIsolationLevel(), setTxIsolationLevel(BitsyIsolationLevel): These methods set the isolation level for this transaction. Future transactions will continue to use the default isolation level

Simulating locks

Vertices or edge that are queried, but not updated by a transaction, do not participate in the version check. For example, if an edge is added between two vertices by a transaction, and a property is concurrently changed in one of the end-point vertices by a different transaction, both transactions will go through.

A transaction can simulate a lock on the vertex or edge, by either setting a property to the currently-held value, or calling the markForUpdate() method defined in the concrete implementations of the Vertex and Edge interfaces, viz. BitsyVertex and BitsyEdge. This ensures that other transactions that update the same edge/vertex after the "lock" operation, but before this transaction commits, will fail with the BitsyRetryException.

An application can also implement locks in Java for pessimistic concurrency control. However, you should make sure that deadlocks are avoided using method such as lock ordering.