Spring's transaction management is a robust abstraction that simplifies handling database transactions, ensuring data integrity and consistency.
1. What is Transaction Management?
A transaction is a sequence of operations performed as a single logical unit of work. In Spring, transaction management ensures that either all operations in a transaction succeed (commit) or none do (rollback), maintaining data consistency.
ACID Properties: Atomicity, Consistency, Isolation, Durability
Atomicity:
The @Transactional annotation wraps multiple database operations within a single transaction. If all operations complete successfully, the transaction is committed and changes are saved. If any operation throws a runtime exception (or another specified exception), Spring automatically rolls back the transaction, undoing all changes made during that transaction
Consistency:
This approach ensures that the database remains in a valid state, preventing partial updates or data corruption. If a constraint is violated or an error occurs, the transaction is aborted and the database is restored to its previous state.
Example Workflow:
Start a transaction (@Transactional method is called).
Perform several database operations (e.g., insert, update).
If all succeed, Spring commits the transaction.
If any operation fails (throws an exception), Spring rolls back all changes-none of the operations have any effect on the database
2 . Spring Transaction Management Approaches
Declarative: Using annotations like @Transactional (most common).
Programmatic: Using TransactionTemplate or PlatformTransactionManager directly.
3. Setting Up Transaction Management
Step 1: Add Dependencies
Spring Data JPA or JDBC
Database driver (e.g., H2, MySQL)
Step 2: Enable Transaction Management
@Configuration
@EnableTransactionManagement
public class AppConfig {
@Bean
public PlatformTransactionManager txManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
4.. Using @Transactional Annotation (Declarative Approach)
Basic Usage:
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
@Transactional
public void createUser(User user) {
userRepository.save(user);
}
}
Explanation:
The createUser method runs inside a transaction. If any exception occurs, the transaction is rolled back.
Output:
On successful save: User is persisted.
On exception: No user is saved (rollback).
5. Transaction Propagation
Propagation defines how transactions behave when a transactional method is called by another transactional method. The most common propagation modes are:
REQUIRED (default): Uses the existing transaction if one exists; otherwise, creates a new one.
REQUIRES_NEW: Suspends any existing transaction and starts a new one.
NESTED: Executes within a nested transaction if a current transaction exists (uses savepoints); otherwise, behaves like REQUIRED.
SUPPORTS: Join if exists, else non-transactional.
6. Isolation Levels and Read-Only Transactions
Isolation Levels
Isolation levels control how transaction integrity is maintained when multiple transactions are running concurrently. Common levels include:
READ_UNCOMMITTED: Lowest level; allows dirty reads.
READ_COMMITTED: Default in many databases; prevents dirty reads.
REPEATABLE_READ: Ensures that if a value is read twice in the same transaction, it remains consistent.
SERIALIZABLE: Highest isolation; fully serializes transactions.
7.Exception Handling and Rollback
Unchecked exceptions (RuntimeException): Trigger rollback by default.
Checked exceptions: Do not trigger rollback unless specified.
@Transactional(rollbackFor = IOException.class)
public void method() throws IOException { ... }
Output:
Rolls back on IOException as well
How does Spring ensure transactional integrity in a distributed environment ?
Can you provide an example of using @Transactional with multiple database operations ?
No comments:
Post a Comment