Sobes.tech
Middle

What does the @Transactional annotation in Spring Data mean?

sobes.tech AI

Answer from AI

The @Transactional annotation in Spring Data indicates that a method or class should be executed within a transaction. Spring AOP (Aspect-Oriented Programming) creates a proxy object around such a method, which manages the transaction lifecycle.

Main actions performed by @Transactional:

  1. Transaction start: A new transaction is opened or an existing one is used before executing the annotated method.
  2. Method execution: The logic of the method itself is executed.
  3. Transaction commit or rollback:
    • If the method completes successfully without exceptions (by default only RuntimeException), the transaction is committed.
    • If an exception is thrown from the method (by default RuntimeException), the transaction is rolled back.

Main attributes of the annotation:

  • propagation: Defines how transactions interact with each other (e.g., REQUIRED, REQUIRES_NEW, SUPPORTS). Default is REQUIRED.
  • isolation: Defines the isolation level of the transaction to prevent issues with concurrent data access (e.g., READ_COMMITTED, REPEATABLE_READ). The database's default isolation level is used.
  • readOnly: Indicates that the transaction should be read-only. Optimizes performance for read operations.
  • timeout: Sets the maximum execution time for the transaction before automatic rollback.
  • rollbackFor: Specifies a list of exception types upon which a rollback should occur. Defaults to rolling back on RuntimeException.
  • noRollbackFor: Specifies a list of exception types upon which a rollback should not occur.

Example usage:

// Service layer example
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;

    @Transactional // This method will be executed within a transaction
    public User createUser(User user) {
        // User creation logic, possibly involving multiple DB operations
        userRepository.save(user);
        // Possibly other save or update operations
        // userRepository.updateRelatedInfo(user.getId(), ...);
        return user;
    }

    @Transactional(readOnly = true) // Read-only method, optimization
    public User findUserById(Long id) {
        return userRepository.findById(id).orElse(null);
    }

    @Transactional(rollbackFor = CustomBusinessException.class) // Rollback on specific user-defined exception
    public void performCriticalOperation(Long userId) throws CustomBusinessException {
        // Critical operation logic
        // May throw CustomBusinessException
    }
}

The @EnableTransactionManagement annotation is usually used in a configuration class to enable support for declarative transaction management.