Spring Data JPA Transaction Management :
A Spring Data JPA Transaction Management has a sequence of actions that are bundled as a single piece of work.
It is an important part of RDMBS-oriented applications to ensure data consistency and integrity.
The transaction is a set of SQL statements that is naturally automatic in nature to manage the data.
It has the following four key properties ACID –
• Atomicity— It refers to whether the entire transaction takes place at once or doesn’t happen at all.
• Consistency—The database must be consistent before and after the transactions are done.
• Isolation—Multiple transactions occur independently without any interference.
• Durability—The changes in a successful transaction occur even if the system failure occurs.
Spring Data JPA Transactional annotation :
The Transactional annotation is used when you want a certain method/class(=all methods inside) to be executed in a transaction.
It will do all the magic we need to do in a programmatic way before handling transaction management.
Any bean’s public method you annotate with the @Transactional annotation will be executed within transaction management.
Example of Spring Data JPA with Transaction Management :

If assume the real-time scenario wants to book a flight ticket we required the Passenger Info and Payment Info details.
Store that data into any RDBMS databases as per requirement.
Any Passenger is not booked the ticket and Payment got failure for any reason due to Payment gateway or network error or any other else.
There is no point to store the unwanted data in the database and for such a case we are not able to generate the acknowledgment for it.
To avoid data inconsistency the transaction management comes either to commit or rollback.
Following is pom.xml, with added dependencies for JPA.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.knoldus</groupId>
<artifactId>flight-service-example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>flight-service-example</name>
<description>Demo project for Spring Boot with-transaction</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Create an application.properties as below –
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306/knoldus_db
spring.datasource.username = root
spring.datasource.password = root
spring.jpa.show-sql = true
spring.jpa.hibernate.ddl-auto = update
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL8Dialect
server.port=9090
Create the appropriate service class and repository classes for Passenger and Payment –
package com.knoldus.transaction.service; import com.knoldus.transaction.dto.FlightBookingAcknowledgement; import com.knoldus.transaction.dto.FlightBookingRequest; import com.knoldus.transaction.entity.PassengerInfo; import com.knoldus.transaction.entity.PaymentInfo; import com.knoldus.transaction.repository.PassengerInfoRepository; import com.knoldus.transaction.repository.PaymentInfoRepository; import com.knoldus.transaction.utils.PaymentUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.UUID; @Service public class FlightBookingService { @Autowired private PassengerInfoRepository passengerInfoRepository; @Autowired private PaymentInfoRepository paymentInfoRepository; @Transactional //(readOnly = false,isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED) public FlightBookingAcknowledgement bookFlightTicket(FlightBookingRequest request) { PassengerInfo passengerInfo = request.getPassengerInfo(); passengerInfo = passengerInfoRepository.save(passengerInfo); PaymentInfo paymentInfo = request.getPaymentInfo(); PaymentUtils.validateCreditLimit(paymentInfo.getAccountNo(), passengerInfo.getFare()); paymentInfo.setPassengerId(passengerInfo.getPId()); paymentInfo.setAmount(passengerInfo.getFare()); paymentInfoRepository.save(paymentInfo); return new FlightBookingAcknowledgement("SUCCESS", passengerInfo.getFare(), UUID.randomUUID().toString().split("-")[0], passengerInfo); } }
Main Application
FlightServiceExampleApplication is the main class, which contains test data to test transaction management. Used @EnableTransactionManagement annotation.
package com.knoldus.transaction; import com.knoldus.transaction.dto.FlightBookingAcknowledgement; import com.knoldus.transaction.dto.FlightBookingRequest; import com.knoldus.transaction.service.FlightBookingService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; importorg.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication @RestController @EnableTransactionManagement public class FlightServiceExampleApplication { @Autowired private FlightBookingService service; @PostMapping("/bookFlightTicket") public FlightBookingAcknowledgement bookFlightTicket(@RequestBody FlightBookingRequest request){ return service.bookFlightTicket(request); } public static void main(String[] args) { SpringApplication.run(FlightServiceExampleApplication.class, args); } }
Run the application by using the IDE Run option or by using the below command
mvn spring-boot:run
Results :


References :
https://github.com/knoldus/Spring-Transaction-Demo-with-Spring-data-JPA