Transaction management in database when two spring boot application trying to access the same record - spring-boot

Two spring boot applications are connected to the common database.
I just wanted to know, how to handle the transaction if both the application try to update the record at the same time?

Since you seem to use JPA (via Spring Data JPA) there isn't much to handle.
The database itself will prevent two transactions to update the record at the same time. So one will always be first.
If you use optimistic locking (which is the default with JPA) the second transaction will notice the modified row and rollback.
Without that the second transaction will simply overwrite the changes with it's own changes.

Related

Spring rollback transaction from 2 Separate Databases

I have a Spring Boot server that collects 2 gRPC microservices - one of them works with the DynamoDB and another CockrachDB database. I need to make sure the commit works fine in both of the DB's and if not need to roll back from both of them.
The issue is if this is successful in the first DB and has an exception into the 2nd, it may not be possible normally to rollback from the 1st DB.
How can I achieve so the commit is either successful or failed in both of the DB's together?
For distributed transaction management frameworks or architectures, you can refer to these links:
https://seata.io/en-us/
https://microservices.io/patterns/data/saga.html
https://medium.com/#dongfuye/the-seven-most-classic-solutions-for-distributed-transaction-management-3f915f331e15
https://dba.stackexchange.com/questions/18435/cap-theorem-vs-base-nosql#:~:text=1%20Answer&text=CAP%20is%20Consistency%2C%20Availability%2C%20and,throws%20consistency%20out%20the%20window.
Hope these links can help.

Programmatically recreate H2 database schema in SpringBoot application (not while unit testing)?

I have a SpringBoot application with in memory H2 database and Spring Data JPA.
I need to configure a #Scheduled job that drops and recreates the schema and loads it with fresh data from a file.
How can I programmatically recreate the schema in my application?
You can use database version control tool like eg Liquibase to create and maintain database schema definition as well as initial data. Than, you will be able to easily invoke database migration including drop of whole schema during applicaiton runtime. IT has some integration with Spring Boot already.
Keep in mind, that you will have to lock database access in order to execute migration - DDL is not transactional, so database will be of no use anyway during the migration process and you app can yeld many errors during that time.
If locking is not an option - you should be able to create another instance or at least separate schema in running instance, run migration against it and if everything is done, "switch" peristence context to use brand new schema (and probably remove the old one)

jdbc is not able to find data flushed by jpa repository in the same transaction

I have a JUnit 5 testcase which is annotated with #Transactional and it is calling save service (which uses JPA saveandFlush) first, and trying to retrieve the same data/entity by using find service, which is using plain JDBC for searching, but it is not able to find that entity.
When I tried using isolation of the transaction as read_uncommitted it threw exception saying "java.sql.SQLException: READ_COMMITTED and SERIALIZABLE are the only valid transaction levels" please note that I am using Oracle database.
Is there any other way we can read the data which is present in same transaction by JDBC code?
Oracle does not implement Read Uncommited isolation level, so you will not be able to see uncommited changes from other sessions.
As Mark Rotteveel and Marmite Bomber said, two different transactions/connections(JPA and JDBC) can not see each other's uncommitted data, specially for application having Oracle database.
I had to use spring managed jdbc template so that JPA and the JDBC template uses the same transaction and data is visible to each other.

How to keep an EntityManager/Session open across multiple transactions in a single thread?

Is there any way to prevent spring data from closing the underlying hibernate session after an #Transactional method in a #Service component? I am writing a simple command line app that reads data from a web service, does some processing and writes to the database. Some of the operations span multiple entities and must be transactional.
However, I am running into too many LazyLoadingExceptions. Apparently the hibernate session is automatically closed by spring after the transaction commits.
In other words, what I am trying to achieve is something like OpenSessionInView, but for a command line app. I could achieve this by using pure JPA and manually handling the entity manager and transactions. However, I would like to know if is there a solution which enables to leverage the spring-data and still achieve the desired behavior.

Should one close Hibernate Session object every time after performing any CRUD operation?

I am working with enterprise application that uses Spring 3.x with Hibernate annotated programming.I am working with hibernate Session object for performing db operations in my XYZDaoImpl class.
And my doubt is "Is it correct way to close Hibernate Session object every time after performing any CRUD operation?"
If it is not the correct way, please advise me the recommended way of opening/closing of hibernate Session Object.
can you post a bit daoImpl code......
If you use sessionFactory.getCurrentSession(), you will get current session..in this case framework automatically flushed and closed when the transaction ends (commit or rollback).
If you use sessionFactory.openSession(), you have to manage the session yourself and to flush and close it "manually".
No, when using hibernate with spring, you should not (manually) open or close sessions, but let spring manage the hibernate session for you. Spring manages the session as a transactional resource, so you have to configure transaction management correctly.
If you open/close the hibernate session manually, you are hardly using the integration between these two frameworks: the session management is the main feature of the integration.
The only reason to open/close a hibernate session in a spring context is to use the same session to span multiple transactions.

Resources