The @Transactional
annotation in Java is part of the Spring Framework and is used to manage transactions declaratively. It simplifies transaction management by allowing developers to define transactional boundaries around methods or classes without needing to write boilerplate code for beginning and committing transactions explicitly.
@Transactional
:@Transactional
to define the transactional behavior for that specific method.@Service
public class UserService {
@Transactional
public void createUser(User user) {
// code to save user to the database
}
}
@Service
@Transactional
public class UserService {
public void createUser(User user) {
// code to save user to the database
}
}
@Transactional
:propagation
: Defines how transactions relate to each other.
REQUIRED
(default): Uses the current transaction or creates a new one if none exists.REQUIRES_NEW
: Suspends the current transaction and creates a new one.MANDATORY
: Requires an existing transaction; throws an exception if none exists.SUPPORTS
: Runs within a transaction if one exists, otherwise runs non-transactionally.NOT_SUPPORTED
: Runs non-transactionally, suspending any existing transaction.NEVER
: Throws an exception if a transaction exists.NESTED
: Executes within a nested transaction if a transaction exists.isolation
: Sets the isolation level for the transaction.
DEFAULT
: Uses the default isolation level of the database.READ_UNCOMMITTED
: Allows dirty reads, non-repeatable reads, and phantom reads.READ_COMMITTED
: Prevents dirty reads, allows non-repeatable reads and phantom reads.REPEATABLE_READ
: Prevents dirty and non-repeatable reads, allows phantom reads.SERIALIZABLE
: Prevents dirty reads, non-repeatable reads, and phantom reads.timeout
: Specifies the timeout for the transaction in seconds.
@Transactional(timeout = 30)
public void processData() {
// transactional code
}
readOnly
: Optimizes the transaction for read-only operations.
@Transactional(readOnly = true)
public List<User> fetchUsers() {
// code to fetch users
}
rollbackFor
and noRollbackFor
: Specifies the exceptions that should trigger a rollback or not.
@Transactional(rollbackFor = CustomException.class)
public void performAction() throws CustomException {
// transactional code
}
@Transactional(
propagation = Propagation.REQUIRED,
isolation = Isolation.READ_COMMITTED,
timeout = 20,
readOnly = false,
rollbackFor = {SQLException.class}
)
public void transferFunds(Account fromAccount, Account toAccount, BigDecimal amount) throws SQLException {
// Code to transfer funds
}
@Service
public class ServiceA {
@Autowired
private ServiceB serviceB;
@Transactional
public void methodA() {
// Business logic for Service A
serviceB.methodB(); // Calls methodB in Service B
}
}
@Service
public class ServiceB {
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void methodB() {
// Business logic for Service B
}
}
methodA
will run in a new transaction or an existing one, while methodB
will always run in a new transaction, suspending the one from methodA
.@Transactional
rolls back on unchecked exceptions (subclasses of RuntimeException
). For checked exceptions, you need to explicitly specify rollback behavior using rollbackFor
.@Transactional
judiciously, especially in performance-critical applications, as it can introduce overhead.@Transactional
are public
as Spring AOP proxies can only apply to public methods.@Transactional
in Spring simplifies transaction management in Java applications by handling the complexities of transaction boundaries, rollbacks, and propagation. It allows developers to focus on business logic while ensuring data integrity and consistency in transactional operations.