Cosmos DB API for MongoDB: Transaction support on Shard key collection

manideep krishna 0 Reputation points
2025-02-25T23:04:26.35+00:00

Hello,

We're using the Cosmos DB API for MongoDB. I just wonder how can we do the transactions on Shard key collection, what is the best practice?

I am using spring boot with spring data jpa.

My expectation is, processMessage() method should not update the count.

@Bean
public MongoTransactionManager transactionManager(MongoDatabaseFactory dbFactory) {
    return new MongoTransactionManager(dbFactory);
}
@Transactional(rollbackFor = RuntimeException.class)
public void processMessage( final TestEntity testEntity) {
    try {
        testEntity.setCount(testEntity.getCount() + 10);
        testRepository.save(testEntity);
        if(true){
            throw new RuntimeException("Error in processing the record");
        }
}
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
Azure Cosmos DB
Azure Cosmos DB
An Azure NoSQL database service for app development.
1,773 questions
{count} votes

Accepted answer
  1. Sai Raghunadh M 2,720 Reputation points Microsoft Vendor
    2025-02-27T21:24:07.54+00:00

    Hi @manideep krishna

    I'm glad that you were able to resolve your issue and thank you for posting your solution so that others experiencing the same thing can easily reference this! Since the Microsoft Q&A community has a policy that "The question author cannot accept their own answer. They can only accept answers by others ", I'll repost your solution in case you'd like to "Accept " the answer.

    Issue:

    Hello,

    We're using the Cosmos DB API for MongoDB. I just wonder how can we do the transactions on Shard key collection, what is the best practice?

    I am using spring boot with spring data jpa.

    My expectation is, processMessage() method should not update the count.

    @Bean
    public MongoTransactionManager transactionManager(MongoDatabaseFactory dbFactory) {
        return new MongoTransactionManager(dbFactory);
    }
    
    @Transactional(rollbackFor = RuntimeException.class)
    public void processMessage( final TestEntity testEntity) {
        try {
            testEntity.setCount(testEntity.getCount() + 10);
            testRepository.save(testEntity);
            if(true){
                throw new RuntimeException("Error in processing the record");
            }
    }
    
    implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
    
    

    Solution:

    this below worked for me.

    @Bean
    
    @Transactional
    

    If you have any other questions or are still running into more issues, please let me know. Thank you again for your time and patience throughout this issue.

    Please remember to "Accept Answer" if any answer/reply helped, so that others in the community facing similar issues can easily find the solution.

    0 comments No comments

2 additional answers

Sort by: Most helpful
  1. Sai Raghunadh M 2,720 Reputation points Microsoft Vendor
    2025-02-26T18:06:21.0666667+00:00

    Hi @manideep krishna

    If your operations are limited to single documents, Cosmos DB ensures atomicity for single-document transactions even in sharded collections.

    If you need to perform multi-document transactions on a sharded collection, consider restructuring your data to fit within a single collection or implementing rollback logic at the application level.

    Please go through these Documentation link and similar thread link that might help you:

    https://learn.microsoft.com/en-us/azure/cosmos-db/mongodb/use-multi-document-transactions

    https://learn.microsoft.com/en-us/answers/questions/751204/cosmos-db-api-for-mongodb-transaction-support-on-m

    Hope this helps. Do let us know if you any further queries.

    0 comments No comments

  2. manideep krishna 0 Reputation points
    2025-02-27T21:13:28.33+00:00

    this below worked for me.

    @Bean
    public MongoTransactionManager transactionManager(MongoDatabaseFactory dbFactory) {
        return new MongoTransactionManager(dbFactory); 
    } 
    
    
    @Transactional
    public void processMessage( final TestEntity testEntity) {
        try {
            testEntity.setCount(testEntity.getCount() + 10);
            testRepository.save(testEntity);
            if(true){
                throw new RuntimeException("Error in processing the record");
            }
    }
    
    

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.