This article and its entire content are awaiting approval and will be released soon. You can get support for custom app development by asking questions in the forum; most questions get answered fairly quickly. Please do not use the contact form or private messages for technical support questions about building custom apps with the Novunex Platform.
This article tells you how to avoid race conditions in a Novunex App. We will first take a look at what race conditions are and why they occur. Then we’ll go on to show how to detect, prevent, and resolve them.
Race Conditions in the Novunex Platform
Race conditions occur when two or more processes are attempting to access a shared resource (e.g., entity) at the same time. This can cause the processes to interfere with each other and generate unexpected results.
A race condition can arise in any software when a computer program has multiple code paths that are executing at in parallel. E.g., two instances are trying to update the same entity in parallel (see example below), therefore, wrong values get stored or processes execute with unexpected behaviour.
How to avoid race conditions
There are multiple ways to avoid race conditions including changing data models or re-designing processes.
Do not execute processes in parallel
The most obvious approach would be to avoid executing processes in parallel at all.
- Avoid running schedules with high frequency accessing the same entities
- Execute processes only based on user input or human tasks
- Set schedules executing processes only at specific dates with limited repetition
- Set processes to Only one concurrent process instance - to avoid parallel execution of the same process
Seperation of concerns
Separation of concerns is a design principle for separating programs into distinct sections. In case of the Novunex Platform that means that only one process updates specific attributes of Entities in order to avoid race conditions.
- Design processes in a way that only one process updates individual attributes and does not share data with other processes
- Design Entity Types in a way that frequently updated data is separated and split into different Entity Types
Use “atomic” operations
Each activity is executed in its own “read commited” transaction, avoiding dirty reads (when a transaction is allowed to read a row that has been modified by an another transaction which is not committed yet) or any other isolation level that may read an undefined state of data. Therefore, any operation within an activity (transaction) shall not be affected by race conditions.
- Use SQL Create / SQL Update activities and directly update entities based on select, join or complex SQL queries
Single point of truth
Do not store calculated values or the same values in multiple entities or entity types.
- Avoid redundant data and do not store data asynchronously in process context and in entities
- Stored data that can be derived based on calculations increases redundancy as well as the chance to inconsistencies