![]() |
VOOZH | about |
Transactions ensure that multiple database operations are executed as a single unit, maintaining data consistency and integrity. In Spring Boot, transaction management is simplified using @Transactional, which automatically handles commit and rollback operations.
Transaction management is the process of coordinating database operations to follow the ACID properties:
Example: In a banking system, if you transfer money:
Both operations should succeed or fail together.
The @Transactional annotation:
Note: If you use spring-boot-starter-data-jpa, Spring Boot auto-configures transaction management, so @EnableTransactionManagement isnβt required. Add it only if youβre not using JPA starter or need custom transaction management.
In this example, we will create an application to store user information along with his address information and will use spring transaction management to resolve the transaction break problem.
Create a Spring Boot project using . Select the following:
We will add the required dependencies for our spring boot application.
π Add DependenciesNow, we will configure the database in our application. We will be using the following configurations and add them to our application.properties file.
server.port=9090
# Database Configuration
spring.datasource.url=jdbc:mysql://localhost:3306/employee_db
spring.datasource.username=root
spring.datasource.password=root
# JPA Configuration
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
Note: Please add your database username & password along with the database path.
We will create two model classes: Employee and Address with a @OneToOne relationship.
Employee.java
Explanation: Represents the Employee entity and maps it to the database with a one-to-one relationship with Address.
Address.java
Explanation: Represents the Address entity linked to Employee using a one-to-one mapping.
In this step, we will create a Repository Layer. For this, we will be creating EmployeeRepository and AddressRepository and will be extending JpaRepository<T, ID> for performing database-related queries.
EmployeeRepository.java
Explanation: Provides CRUD operations for Employee using Spring Data JPA.
AddressRepository.java
We can use @Transactional annotation in service layer which will result interacting with the database. In this step, we will create a service layer for our application and add business logic to it. For this, we will be creating two classes EmployeeService and AddressService. In EmployeeService class we are throwing an exception.
EmployeeService.java
Explanation: Contains business logic and uses @Transactional to ensure atomic operations on Employee and Address.
AddressService.java
Explanation: Handles business logic related to Address operations..
In this step, we will create a controller for our application. For this, we will create a Controller class and add all the mappings to it.
Controller.java
Explanation: Exposes REST APIs to handle client requests for Employee and Address operations
TransactionManagementApplication.java
Explanation: This is the main Spring Boot class that starts the application and enables transaction management using @EnableTransactionManagement
In this step, we will run our application. Once, we run our application using hibernate mapping in our database required tables will be created.
π Output_screenExplanation: Spring Boot is auto-generating the database schema and setting up relationships when the application starts.
As we can see in logs, our table has been created. We can also confirm it by looking at our database.
π Database_logsπ Adding Employee_postman{
"name": "ankur"
}
As we can see in the above response we have added an employee. We can also check our database for employee data and address data.
π Employee Data_in_databaseSimilarly, we can also check for address data.
π Address Data_in_databaseIf we donβt use transaction management, partial data may persist in the database even if an error occurs.
Example: In the EmployeeService class, we deliberately initialize the Address object as null. This will cause a NullPointerException when we try to save the address, but the employee record will still be saved in the database.
Now, we will delete our table from the database and again run our application and will request the application to create an employee.
As we can see in the above media file, we have initialized the address object as null and requested the application, we have an employee created in the database but the address information is not, as we have received a null pointer exception. But, this is not good practice in transaction management, as employees should be saved only when the address is saved and vice-versa.
To solve this, we use @Transactional.
TransactionManagementApplication.java
Update EmployeeService:
1. Run the Spring Boot application.
2. When making a request to add an employee:
Note: This ensures data consistency: either both tables are updated or neither is updated.
As we can see in the above media file, this time the employee data do not get stored in the database, nor did the address data. This way the spring has handled the transaction that both employees and address data gets stored or no data gets stored.