Alternative Design Patterns for Long-Running Transactional Methods in Monolith Application

40 views Asked by At

Hello Stack Overflow community,

I am working on a monolith application with a single PostgreSQL database, and I have methods that need to be transactional but involve time-consuming operations. Consider the following example:

void sample(Item item) {
    Item2 item2 = saveData1();
    createPDF(item2.id);
    savePdf();
    saveData2()
}

I am hesitant to make the entire method @Transactional because it could potentially block the database for an extended period. While I am aware of the saga design pattern for handling rollbacks in case of issues, it seems a bit too complex for this specific use case.

I am seeking advice on alternative design patterns or solutions that would allow me to maintain transactional integrity without blocking the database for an extended time. Are there any established best practices or design patterns for handling such scenarios in a monolith application?

Thank you for your insights!

What I tried:

I attempted to execute the sample method within my monolith application.

What I expected to happen:

I anticipated the method to execute successfully, completing the transactional operations within a reasonable time frame.

What actually resulted:

However, I observed that making the entire method @Transactional caused the database to be blocked for an extended period, impacting performance. I am now exploring alternative design patterns or solutions to address this issue.

1

There are 1 answers

0
AndrewR On

What will happen if the transaction does roll back? E.g. the code created and saved a PDF, will the PDF be removed on rollback?

With the question I am trying to explore if a transaction is actually needed? May be the system may afford some inconsistency? Maybe the system may afford some temporary inconsistency and have a separate process to clean it up later?

Another approach is to decouple heavy calculations from actual transactional update. For example, is there a way to create PDF outside of transaction? And then run all save/update operations? Clearly, you need an ID from the database to generate the PDF, is there an option to optimize that? Can we use an external ID generator for this?

Another angle: why the database is locked? Is it the entire database being locked or just some rows/records/objects? Is there a space for an external lock service?

TL;DR - I would either explore Saga approach or move all expensive operations out of transactional code; and the second approach would be my preferred vector of exploration, as that makes sense even in Saga context.