In previous article, we have seen how to enable multi-region writes in Cosmos DB. But multi-region writes can lead to conflicts. In this article, let’s have a look at how the conflicts can be resolved.
What are conflicts ?
When multi-region writes are enabled, multiple replicas are available in different Azure regions. Different users are performing different operations on entities. One user may delete one entity in one Azure region, while the same entity may be just updated in another Azure region by some other user. So, when replicas synchronize, what should be status of that entity ? Should it be marked as deleted ? OR should it be marked as non-deleted and just updated ?
This situation is referred to as conflicts.
What are types of conflicts ?
There are three types of update conflicts which may occur:
- Insert Conflicts: Occur when items with same unique index properties are simultaneously inserted in two or more regions. For example, item with same id property are added in two regions.
- Replace Conflicts: Occur when an item is updated in two or more regions simultaneously
- Delete Conflicts: Occur when application deletes an item in one Azure region and updates the same item in another region.
What are ways to resolve conflicts ?
If you enable multi-region writes and then if you go to containers in data explorer, you can find conflict resolution under settings as shown below.
You can see that there are two modes which you can use for conflict resolution. You can select below two conflict resolving mechanisms on Azure containers:
Last Write Wins (LWW)
When you select this button, you can see a conflict resolver property which is set to _ts (timestamp). If you are using Core SQL API, you can set any numeric property instead of _ts.
In this mode, if a conflict occurs, then the record with highest conflict resolver property value will win and it will be updated in all the copies of Cosmos DB.
When delete conflicts are involved, the deleted version always wins over either insert or replace conflicts. This outcome occurs no matter what the value of the conflict resolution path is.
Merge Procedure (Custom)
If you select this option, then you need to provide the stored procedure name. By default the stored procedure name is empty.
If you keep the merge stored procedure empty and if the conflicts occur, then the conflicts go to conflicts feed. If you specify a procedure name and it throws exception and fails, then also conflicts go to conflicts feed.
If you specify procedure name, then system invokes this stored procedure when conflicts are detected. The procedure accepts two records, original version and conflicted version. The stored procedure can have logic to resolve the conflicts.
The system provides exactly once guarantee for the execution of a merge procedure as part of the commitment protocol.
There is very nice how to article about conflict resolution. If you are curious about implementation details, you can refer to that article.
I hope this article was helpful. Let me know your thoughts.