Skip to content

Transaction Isolation

Using Backendless transactions API you can configure an isolation level for your transaction. The isolation level determines how the Backendless database separates your transaction from all others running at the same time. Without any isolation one transaction could modify the data another transaction is reading and by doing so data inconsistency would be created. Isolation levels determine how isolated your transaction is from others. This is implemented by applying a lock on the data retrieved in a transaction. Different levels of isolation imply different locking mechanisms, which also yield various data read phenomena (described further in this section).

Backendless supports four isolation levels - ordered from lowest to the highest:

  • Read uncommitted
  • Read committed
  • Repeatable read
  • Serializable

Read uncommitted

This is the lowest level of isolation, providing the minimum amount of data isolation. Your transaction can see changes made by other transactions which are not committed yet. This typically is referred to as "dirty read". It means your transaction with this level of isolation could be reading data written by another transaction that eventually will not be there in case if that other transaction is rolled-back. This isolation level yields the best performance, however, it also presents a phenomena commonly referred to as "Dirty reads". See the diagram below for an illustration of "Dirty reads" with the "Read uncommitted" isolation level:

read-uncommitted

To set this isolation level for your transaction, use the API below:

UnitOfWork unitOfWorkInstance = new UnitOfWork();
unitOfWorkInstance.setIsolationLevel( IsolationLevelEnum.READ_UNCOMMITTED );

Read committed

With this isolation level, any uncommitted changes are not visible to other transactions until they are committed. Each Retrieving objects operation returns the data which is guaranteed to be committed into the database, however, this also means, that the any two Retrieving objects operations for the same data object may be returning different results each time  they run within the same transaction. This phenomena is referred as "Non-repeatable reads". The diagram below illustrates it:

read-committed

To set this isolation level for your transaction, use the API below:

UnitOfWork unitOfWorkInstance = new UnitOfWork();
unitOfWorkInstance.setIsolationLevel( IsolationLevelEnum.READ_COMMITTED );

Repeatable read

The level of isolation increases with Repeatable read when compared to Read uncommitted/committed. With this isolation level, All Retrieving objects queries will be returning same result, except for the queries which apply to a range of objects. This means if you run a query retrieving a specific object from two different data retrieval operations in the same transaction, you will be receiving the same data object back.

The database puts read and write locks on the retrieved data objects. As a result, two different transactions may retrieve the same object and subsequently update values for different properties/columns in it resulting in a mix of values in the same object committed to the database. Additionally, since the read/write lock enabling the isolation cannot be obtained for a range of objects, this isolation level presents a phenomena referred to as "Phantom reads". This means that with this isolation level it is possible for a Retrieving objects query to return different results when it runs multiple times in the same transaction. The diagram below illustrates the "phantom read" phenomena with this level of isolation:

phantom-read

The "Repeatable read" is the default isolation level in the Backendless Database. To set this isolation level for your transaction, use the API below:

UnitOfWork unitOfWorkInstance = new UnitOfWork();
unitOfWorkInstance.setIsolationLevel( IsolationLevelEnum.REPEATABLE_READ );

Serializable

This is the highest level of data isolation. The database provides read/write locks for the entire set of objects retrieved in a transaction. The obtained locks are exclusive to the transaction which retrieved data and remain in place until the transaction is committed. To set this isolation level for your transaction, use the API below:

UnitOfWork unitOfWorkInstance = new UnitOfWork();
unitOfWorkInstance.setIsolationLevel( IsolationLevelEnum.SERIALIZABLE );

The table below contains a summary for various read phenomena described above as they relate to the isolation levels:

Isolation levels ↓ Read phenomena →
Dirty reads
Non-repeatable reads
Phantom reads
Read uncommitted
YES
YES
YES
Read committed
NO
YES
YES
Repeatable read
NO
NO
YES
Serializable
NO
NO
NO