azure-cosmosdbazure-cosmosdb-changefeed

Change Feed order when multiple documents are created in a single stored procedure call


We have a system that uses a stored procedure to create documents in a CosmosDb collection, with an auto-incrementing Version property. So if I hand it 2 documents for a logical partition that doesn't yet exist, it will create 2 documents in this order:

{ Version: 0 }
{ Version: 1 }

These are all part of a transaction and get the same _ts value.

We are using change feed to react to the creation of these documents. Because the documents are created in chronological order, we expect our change feed to receive Version 0 and then Version 1. However, on occasion, we will get these changes out of order.

My guess is that Cosmos DB doesn't define the ordering beyond the _ts value, and even though createDocument was called first for Version 0, and then for Version 1, Cosmos DB isn't necessarily storing the documents in a way that maintains that fact.

Can someone with strong knowledge of the Cosmos DB internals confirm or deny my assumption? Is there any good way to mitigate this ordering problem, and ensure that the change feed always receives Version 0 before Version 1, aside from called the stored procedure once for Version 0 and then again for Version 1?


Solution

  • The ordering of the Change Feed is not _ts but lsn which is the transaction identifier (for multi-write region accounts, given the different times and possibilities of conflicts, crts is used). Stored Procedure execution commits as a single transaction, so all documents created on the execution have the same lsn and come within the same Change Feed response.

    This is mentioned in the documentation that covers setting a Max on the Change Feed responses, such as WithMaxItems.

    Because all these items are within the same transaction, this would reflect the behavior you are seeing. There is no specification about guarantees for ordering within the same transaction.

    In your case, Version 0 and 1 will be in the same Change Feed response (delivered in the same batch), so you could in theory, order the items by lsn (which is a property in the document you receive) and Version to obtain the order based on your logic?