Tuesday, May 2, 2023

How to use @EnableTransactionManagement in Spring Framework and Spring Boot? Example Tutorial

Spring Boot has a lot many annotations within its framework that a person can use. If you are searching for one, you have come to the right place. Needless to say, these annotations are essential for building a Spring Boot web application. Today we will look at an annotation that is widely used for transaction management in spring. So, what's the wait?! Let's start! But, before jumping into the sea of spring, let's first understand what a transaction means in spring and what it signifies. A transaction is used in Spring JPA which communicates to the database. we all know what a transaction represents on a database level. If not, no worries! let us all recall.


What is a Transaction?

A database transaction is a set of operations that are considered as if they were a single piece of work. These activities should either finish completely or have no impact. To assure data integrity and consistency, transaction management is a crucial aspect of RDBMS-based corporate applications.

The following four important qualities may be used to characterize the idea of transactions:
  • A transaction should be viewed as a single unit of operation, which implies the complete sequence of activities is either successful or failed.
  • Consistency refers to the database's referential integrity, as well as the use of unique primary keys in tables.
  • Isolation Several transactions with the same data set may be processed at the same time. To avoid data corruption, each transaction should be separated from the others.
  • Durability Upon completion of a transaction, the results must be made permanent and cannot be removed from the database due to a system failure.
For each transaction, a genuine RDBMS database system will ensure all four qualities. The following is a simplified depiction of a transaction issued to the database using SQL:

  • Use the begin transaction command to start the transaction.
  • SQL queries may be used to perform numerous delete, update, and insert operations.
  • If all of the actions are successful, commit them; otherwise, roll back all of them.

On top of many underlying transaction management APIs, the Spring framework offers an abstract layer. By introducing transaction capabilities to POJOs, Spring's transaction support seeks to provide an alternative to EJB transactions. 

Both declarative and programmatic transaction management is supported by Spring. Although EJBs require the use of an application server, Spring transaction management may be handled without one.




@EnableTransactionManagement annotation in Spring 

Similar to the support provided in Spring's <tx:*> XML namespace, this property enables Spring's annotation-driven transaction management functionality. To set up classic, imperative transaction management or reactive transaction management, utilize @Configuration classes.

1. The annotation-driven transaction management functionality is enabled by the @EnableTransactionManagement attribute. @Configuration classes take advantage of it.

2. The @EnableTransactionManagement property configures either classical, imperative, or reactive transaction management.

3. In the configuration class, construct a PlatformTransactionManager bean for imperative transaction management.

4. In the configuration class, construct a ReactiveTransactionManager bean for reactive transaction management.

5. The XML namespace <tx:annotation-driven/> is similar to the @EnableTransactionManagement annotation.


This is all theoretical, let's deep dive into code and understand how it works. Let's create a spring project and a config class to handle all the configurations of our project.

How is @EnableTransactionManagement used in Spring and Spring  Boot ? Example Tutorial



Find below the sample configuration class. you can add the imports on the go in your ide.


@Configuration @EnableTransactionManagement public class AppConfig { @Bean public Cricketer cricketer() { return new Cricketer(); } @Bean public HibernateTemplate hibTemp() { return new HibernateTemplate(sessionFactory(), true); } @Bean public SessionFactory sessionFactory() { SessionFactory sf = new AnnotationConfiguration().configure() .buildSessionFactory(); return sf; } @Bean public HibernateTransactionManager hibTransMan(){ return new HibernateTransactionManager(sessionFactory()); } }




Now, let's create a Cricketer object class for the same.



@Entity public class Cricketer implements Serializable { private static final long serialVersionUID = 1L; @Id private int id; private String name; public Cricketer(){ } public Cricketer(int id,String name){ this.id=id; this.name=name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }



Now, let's create a sample class to test our code,


public class AppTest { public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(AppConfig.class); ctx.refresh(); HibernateTemplate hibtemp= ctx.getBean(HibernateTemplate.class); Cricketer c1= new Cricketer(1,"Virat"); hibtemp.persist(c1); Cricketer c2= new Cricketer(2,"Rohit"); hibtemp.save(c2); } }




Now, if you guys are wondering what is happening, just take a look. The @EnableTransactionManagement annotation enables the processing of transactions in spring with the use of the @Transactional annotation. you can use @Transactional annotation only if you have @EnableTransactionalManagement used in your app-config class or in the XML configuration file.

@EnableTransactionManagement Example in Spring



To quote the same from spring docs, the below configuration file is the same as the XML file. Have a look.


config file : 

@Configuration @EnableTransactionManagement public class AppConfig { @Bean public FooRepository fooRepository() { // configure and return a class having @Transactional methods return new JdbcFooRepository(dataSource()); } @Bean public DataSource dataSource() { // configure and return the necessary JDBC DataSource } @Bean public PlatformTransactionManager txManager() { return new DataSourceTransactionManager(dataSource()); } }


XML file : 


<beans> <tx:annotation-driven/> <bean id="fooRepository" class="com.foo.JdbcFooRepository"> <constructor-arg ref="dataSource"/> </bean> <bean id="dataSource" class="com.vendor.VendorDataSource"/> <bean id="transactionManager" class="org.sfwk...DataSourceTransactionManager"> <constructor-arg ref="dataSource"/> </bean> </beans>



@EnableTransactionManagement is responsible for registering the necessary Spring components that power annotation-driven transaction management, such as the TransactionInterceptor and the proxy- or AspectJ-based advice that weaves the interceptor into the call stack when JdbcFooRepository's @Transactional methods are invoked, in both of the scenarios above.

The name of the TransactionManager bean differs somewhat between the two examples: The name is "txManager" (per the name of the method) in the @Bean case and "transactionManager" in the XML case. By default, @EnableTransactionManagement looks for a bean called "transactionManager," but it's more flexible; it'll fall back to a by-type lookup for any TransactionManager bean in the container.


Conclusion

In this article, we learned about different ways of enabling the transaction along with the @EnableTransactionManagement annotation, how it is used and where and how to use it. We also saw the equivalent XML configuration file. Now, you guys are all set and ready to try it yourself and use the power of spring in your projects! 

Other Spring Framework articles you may like to explore 

Thanks for reading this article so far. If you like these Spring @EnableTransactionManagement annotation tutorials and examples then, please share them with your friends and colleagues. If you have any questions or feedback, then please drop a note.

No comments:

Post a Comment