What is the usage of @Transactional in Java?

@Transactional is an annotation in Java that is used to indicate that a method should be executed within a transaction. It can be applied at the class level or method level.

When @Transactional annotation is used at the class level, transactions will be applied to all methods within the class. This implies that each method in the class will be wrapped within a transaction, and when one method calls another method, they will be executed within the same transaction.

When using the @Transactional annotation at the method level, only the annotated method will be executed within a transaction. This allows you to selectively wrap certain methods in a transaction, while others will not be.

The @Transactional annotation can have various attributes to define the behavior of the transaction, such as propagation, isolation level, timeout, and so on. Some common attributes include:

  1. Propagation refers to the definition of how transactions are spread within a method call chain, indicating how transactions are handled. For example, REQUIRES_NEW signifies that a new transaction is created with each call.
  2. Isolation: This defines the level of isolation of a transaction, determining how transactions are handled in a concurrent environment. Common isolation levels include READ_COMMITTED and SERIALIZABLE.
  3. Timeout: determines the maximum amount of time a transaction can go without being submitted before it automatically rolls back.
  4. readOnly: Indicates whether the transaction is read-only. If the transaction only involves read operations, it can be set to true to improve performance.

Here is an example using the @Transactional annotation:

@Service
@Transactional
public class ProductService {
    
    @Autowired
    private ProductRepository productRepository;
    
    public void createProduct(Product product) {
        productRepository.save(product);
    }
    
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void updateProduct(Product product) {
        productRepository.save(product);
    }
    
    @Transactional(readOnly = true)
    public Product getProductById(Long id) {
        return productRepository.findById(id).orElse(null);
    }
}

In the example above, the createProduct and getProductById methods will be executed within the same transaction. The updateProduct method will be executed in a new transaction, even if it is called by the createProduct method.

bannerAds