• Java Arrays
  • Java Strings
  • Java Collection
  • Java 8 Tutorial
  • Java Multithreading
  • Java Exception Handling
  • Java Programs
  • Java Project
  • Java Collections Interview
  • Java Interview Questions
  • Spring Boot
  • Best Practices For Structuring Spring Boot Application
  • Spring Boot - Start/Stop a Kafka Listener Dynamically
  • How To Dockerize A Spring Boot Application With Maven ?
  • Dynamic Dropdown From Database using Spring Boot
  • Spring - RestTemplate
  • Spring Boot - Scheduling
  • Spring Boot - Sending Email via SMTP
  • Different Ways to Establish Communication Between Spring Microservices
  • JSON using Jackson in REST API Implementation with Spring Boot
  • How to encrypt passwords in a Spring Boot project using Jasypt
  • Containerizing Spring Boot Application
  • How to Send Images in Spring Boot without using Servlet and Redundant JSP Codes?
  • How to Create Todo List API using Spring Boot and MySQL?
  • Spring Boot - Transaction Management Using @Transactional Annotation
  • Spring Boot - Map Entity to DTO using ModelMapper
  • Spring Boot | How to consume JSON messages using Apache Kafka
  • Spring Boot | How to consume string messages using Apache Kafka
  • Spring Boot | How to publish String messages on Apache Kafka
  • Spring Boot | How to publish JSON messages on Apache Kafka
  • Spring Boot - Consume JSON Object From Kafka Topics
  • Spring Boot Kafka Producer Example
  • Spring Boot Kafka Consumer Example
  • Message Compression in Apache Kafka using Spring Boot
  • Spring Boot - Create and Configure Topics in Apache Kafka
  • How to Test Spring Boot Project using ZeroCode?

Spring Boot – Transaction Management Using @Transactional Annotation

@Transactional annotation is the metadata used for managing transactions in the Spring Boot application. To configure Spring Transaction , this annotation can be applied at the class level or method level. In an enterprise application, a transaction is a sequence of actions performed by the application that together pipelined to perform a single operation. For example, booking a flight ticket is also a transaction where the end user has to enter his information and then make a payment to book the ticket.

Why Do We Need Transaction Management?

Let’s understand transactions with the above example, if a user has entered his information the user’s information gets stored in the user_info table. Now, to book a ticket he makes an online payment and due to some reason(system failure) the payment has been canceled so, the ticket is not booked for him. But, the problem is that his information gets stored on the user_info table. On a large scale, more than thousands of these things happen within a single day. So, it is not good practice to store a single action of the transaction(Here, only user info is stored not the payment info).

To overcome these problems, spring provides transaction management, which uses annotation to handle these issues. In such a scenario, spring stores the user information in temporary memory and then checks for payment information if the payment is successful then it will complete the transaction otherwise it will roll back the transaction and the user information will not get stored in the database.

@Transactional Annotation

In Spring Boot, @Transactional annotation is used to manage transactions in a Spring boot application and used to define a scope of transaction. This annotation can be applied to the class level or method level. It provides data reliability and consistency. When a method is indicated with @Transactional annotation, it indicates that the particular method should be executed within the context of that transaction. If the transaction becomes successful then the changes made to the database are committed, if any transaction fails, all the changes made to that particular transaction can be rollback and it will ensure that the database remains in a consistent state.

Note: To use @Transactional annotation, you need to configure transaction management by using @EnableTransactionManagement to your main class of Spring Boot application.

Configure Transaction in Spring Boot

In this example, we will create an application to store user information along with his address information and will use spring transaction management to resolve the transaction break problem.

Step By Step Implementation of Transaction Management

Step 1: create a spring boot project.

In this step, we will create a spring boot project. For this, we will be using Spring Initializr . To create a spring boot project please refer to How to Create a Spring Boot Project?

Step 2: Add Dependencies

We will add the required dependencies for our spring boot application.

Add Dependencies

Step 3: Configure Database

Now, we will configure the database in our application. We will be using the following configurations and add them to our application.properties file.

Note : Please add your database username & password along with the database path.

Step 4: Create Model Class

In this step, we will create our model class. Here, we will be creating two model classes, Employee and Address . While creating the model class we will be using Lombok Library .

Employee.java

Address.java

Step 5: Create a Database Layer

In this step, we will create a database layer. For this, we will be creating EmployeeRepository and AddressRepository and will be extending JpaRepository<T, ID> for performing database-related queries.

EmployeeRepository.java

AddressRepository.java

Step 6: Create a Service Layer

You can use @Transactional annotation in service layer which will result interacting with the database. In this step, we will create a service layer for our application and add business logic to it. For this, we will be creating two classes EmployeeService and AddressService . In EmployeeService class we are throwing an exception.

EmployeeService.java

AddressService.java

Step 7: Create Controller

In this step, we will create a controller for our application. For this, we will create a Controller class and add all the mappings to it.

Controller.java

Step 8: Running Our Application

In this step, we will run our application. Once, we run our application using hibernate mapping in our database required tables will be created.

Output_screen

As we can see in logs, our table has been created. We can also confirm it by looking at our database.

Database_logs

Now, we will request our application for adding an employee to it, using postman. To learn more about postman please refer to Postman – Working, HTTP Request & Responses . Once, we hit the request, the request moves from the controller to the service layer where our business logic is present .

Adding Employee_postman

As we can see in the above response we have added an employee. We can also check our database for employee data and address data.

Employee Data_in_database

Similarly, we can also check for address data.

Address Data_in_database

Step 9: Problem Without Transaction Management

In the EmployeeService class, we initialize the address object to NULL. Consequently, the employee’s details cannot be stored in the database due to the null address object. However, as we are not employing transaction management, the employee basic information will persisted in the database. The address details are omitted because of the null value.

Note: Applying the @Transactional annotation to a method will not trigger a rollback of any operation if @EnableTransactionManagement is not used.

Now, we will delete our table from the database and again run our application and will request the application to create an employee.

As we can see in the above media file, we have initialized the address object as null and requested the application, we have an employee created in the database but the address information is not, as we have received a null pointer exception. But, this is not good practice in transaction management, as employees should be saved only when the address is saved and vice-versa.

Step 10: Transaction Management

To overcome this problem, we will use @Transactional annotation. This will ensure that the transaction should be complete. That is, either both employee and address data should be stored or nothing will get stored . For using transaction management, we need to use @EnableTransactionManagement in the main class of our spring boot application and also, and we need to annotate our addEmployee() method in EmployeeService class with @Transactional annotation.

TransactionManagementApplication.java

Step 11: Running Application

Now, we have enabled transaction management for our application. We will again delete the tables from our database and request our application to add an employee.

As we can see in the above media file, this time the employee data do not get stored in the database, nor did the address data. This way the spring has handled the transaction that both employees and address data gets stored or no data gets stored.

In this article, we have learned basic configuration of transaction management using in a Spring Boot application. Also we have covered @Transactional and @EnableTransactionManagement annotation and it’s uses with a step by step implementation in a spring boot application.

Please Login to comment...

Similar reads.

author

  • Java-Spring-Boot
  • Technical Scripter 2022
  • Technical Scripter

Improve your Coding Skills with Practice

 alt=

What kind of Experience do you want to share?

Vlad Mihalcea

  Leave a Comment

Posted on January 19, 2022 by vladmihalcea

The best way to use the Spring Transactional annotation

Imagine having a tool that can automatically detect JPA and Hibernate performance issues. Wouldn’t that be just awesome? Well, Hypersistence Optimizer is that tool! And it works with Spring Boot, Spring Framework, Jakarta EE, Java EE, Quarkus, or Play Framework. So, enjoy spending your time on the things you love rather than fixing performance issues in your production system on a Saturday night!

Introduction

In this article, I’m going to show you the best way to use the Spring Transactional annotation.

This is one of the best practices I applied when developing RevoGain, a web application that allows you to calculate the gains you realized while trading stocks, commodities, or crypto using Revolut .

Spring Transactional annotation

Right from the 1.0 version, Spring offered support for AOP-based transaction management that allowed developers to define the transaction boundaries declaratively. I know this because I was reading its manual in the autumn of 2004:

The reason why I started using @springframework in 2004 is because of its manual written by @springrod and the team. I was sold right away. Never underestimate the impact of documentation. https://t.co/fpJsn2F1sA pic.twitter.com/Dmgnsir1bT — Vlad Mihalcea (@vlad_mihalcea) February 17, 2021

Very soon after, in the 1.2 version, Spring added support for the @Transactional annotation , which made it even easier to configure the transaction boundaries of business units of work.

The @Transactional annotation provides the following attributes:

  • value and transactionManager – these attributes can be used to provide a TransactionManager reference to be used when handling the transaction for the annotated block
  • propagation – defines how the transaction boundaries propagate to other methods that will be called either directly or indirectly from within the annotated block. The default propagation is REQUIRED and means that a transaction is started if no transaction is already available. Otherwise, the in-progress transaction is going to be used by the current running method.
  • timeout and timeoutString – define the maximum number of seconds the current method is allowed to run before throwing a TransactionTimedOutException
  • readOnly – defines if the current transaction is read-only or read-write.
  • rollbackFor and rollbackForClassName – define one or more Throwable classes for which the current transaction will be rolled back. By default, a transaction is rolled back if a RuntimException or an Error is thrown, but not if it throws a checked Exception .
  • noRollbackFor and noRollbackForClassName – define one or more Throwable classes for which the current transaction will not be rolled back. Normally, you’d use these attributes for one or more RuntimException classes for which you don’t want to roll back a given transaction.

What layer does the Spring Transactional annotation belong to?

The @Transactional annotation belongs to the Service layer because it is the Service layer’s responsibility to define the transaction boundaries.

Don’t use it in the Web layer because this can increase the database transaction response time and make it more difficult to provide the right error message for a given database transaction error (e.g., consistency, deadlock, lock acquisition, optimistic locking).

The DAO (Data Access Object) or Repository layer requires an application-level transaction, but this transaction should propagate from the Service layer.

In the Service layer, you can have both database-related and non-database-related services. If a given business use case needs to mix them, like when it has to parse a given statement, build a report, and save some results to the database, it’s best if the database transaction is started as late as possible.

For this reason, you could have a non-transactional gateway service, like the following RevolutStatementService :

The processRevolutStocksStatement method is non-transactional, and, for this reason, we can use the Propagation.NEVER strategy to make sure that this method is never ever called from an active transaction.

The statementParser.parse and the generateReport method are, therefore, executed in a non-transactional context as we don’t want to acquire a database connection and hold it necessarily when we only have to execute application-level processing.

Only the operationService.addStatementReportOperation requires to execute in a transactional context, and for this reason, the addStatementReportOperation uses the @Transactional annotation:

Note that the addStatementReportOperation overrides the default isolation level and specifies that this method is executed in a SERIALIZABLE database transaction.

Another thing worth noting is that the class is annotated with @Transactional(readOnly = true) , meaning that, by default, all service methods will use this setting and execute in a read-only transaction unless the method overrides the transactional settings using its own @Transactional definition.

For transactional services, it’s good practice to set the readOnly attribute to true at the class level and override it on a per-method basis for the service methods that need to write to the database.

For instance, the UserService uses the same pattern:

The loadUserByUsername uses a read-only transaction, and since we are using Hibernate, Spring performs some read-only optimizations as well .

On the other hand, the createUser has to write to the database. Hence, it overrides the readOnly attribute value with the default setting given by the @Transactional annotation, which is readOnly=false , therefore making the transaction read-write.

Another great advantage of splitting read-write and read-only methods is that we can route them to different database nodes, as explained in this article .

Read-write and read-only transaction routing with Spring

This way, we can scale read-only traffic by increasing the number of replica nodes.

Awesome, right?

If you enjoyed this article, I bet you are going to love my Book and Video Courses as well.

The Spring Transactional annotation is very handy when it comes to defining the transaction boundaries of business methods.

While the default attribute values were properly chosen, it’s good practice to provide both class-level and method-level settings to split use cases between non-transactional, transactional, read-only, and read-write use cases.

Transactions and Concurrency Control eBook

 Category: Spring      Tags: annotation , service layer , spring , Spring Boot , Transactional , transactions

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Notify me of follow-up comments by email.

This site uses Akismet to reduce spam. Learn how your comment data is processed .

Let’s connect

Find article.

High-Performance Java Persistence Book

Video Courses

High-Performance Java Persistence Video Course

Hypersistence Optimizer

Hypersistence Optimizer

Social Media

  • Privacy Policy
  • Terms of Service
  • Cookie Policy (EU)
  • Entries feed
  • Comments feed
  • WordPress.org

Powered by WordPress.com .

Spring Transaction Management: @Transactional In-Depth

Last updated on june 03, 2022 -.

You can use this guide to get a simple and practical understanding of how Spring's transaction management with the @Transactional annotation works.

The only prerequisite? You need to have a rough idea about ACID, i.e. what database transactions are and why to use them. Also, distributed transactions or reactive transactions are not covered here, though the general principles, in terms of Spring, still apply.

Introduction

In this guide you are going to learn about the main pillars of Spring core’s transaction abstraction framework (a confusing term, isn’t it?) - described with a lot of code examples:

@Transactional (Declarative Transaction Management) vs Programmatic Transaction Management.

Physical vs Logical transactions.

Spring @Transactional and JPA / Hibernate integration.

Spring @Transactional and Spring Boot or Spring MVC integration.

Rollbacks, Proxies, Common Pitfalls and much more.

As opposed to, say, the official Spring documentation , this guide won’t confuse you by diving right into the topic Spring-first .

Instead you are going to learn Spring transaction management the unconventional way : From the ground up, step by step. This means, starting with plain old JDBC transaction management.

Because everything that Spring does is based on these very JDBC basics. And you’ll save a ton of time with Spring’s @Transactional annotation later, if you grasp these basics.

How plain JDBC Transaction Management works

If you are thinking of skipping this section, without knowing JDBC transactions inside-out: don’t .

How to start, commit or rollback JDBC transactions

The first important take-away is this: It does not matter if you are using Spring’s @Transactional annotation, plain Hibernate, jOOQ or any other database library.

In the end, they all do the very same thing to open and close (let’s call that 'manage') database transactions. Plain JDBC transaction management code looks like this:

You need a connection to the database to start transactions. DriverManager.getConnection(url, user, password) would work as well, though in most enterprise-y applications you will have a data source configured and get connections from that.

This is the only way to 'start' a database transaction in Java, even though the name might sound a bit off. setAutoCommit(true) makes sure that every single SQL statement automatically gets wrapped in its own transaction and setAutoCommit(false) is the opposite: You are the master of the transaction(s) and you’ll need to start calling commit and friends. Do note, the autoCommit flag is valid for the whole time your connection is open, which means you only need to call the method once, not repeatedly.

Let’s commit our transaction…​

Or, rollback our changes, if there was an exception.

Yes, these 4 lines are (oversimplified) everything that Spring does whenever you are using the @Transactional annotation. In the next chapter you’ll find out how that works. But before we go there, there’s a tiny bit more you need to learn.

(A quick note for smarty-pants: Connection pool libraries like HikariCP might toggle the autocommit mode automatically for you, depending on the configuration. But that is an advanced topic.)

How to use JDBC isolation levels and savepoints

If you already played with Spring’s @Transactional annotation you might have encountered something like this:

We will cover nested Spring transactions and isolation levels later in more detail, but again it helps to know that these parameters all boil down to the following, basic JDBC code:

This is how Spring sets isolation levels on a database connection. Not exactly rocket science, is it?

Nested transactions in Spring are just JDBC / database savepoints. If you don’t know what a savepoint is, have a look at this tutorial , for example. Note that savepoint support is dependent on your JDBC driver/database.

How Spring’s or Spring Boot’s Transaction Management works

As you now have a good JDBC transaction understanding, let’s have a look at how plain, core Spring manages transactions. Everything here applies 1:1 to Spring Boot and Spring MVC, but more about that a bit later..

What actually is Spring’s transaction management or its (rather confusingly named) transaction abstraction framework?

Remember, transaction management simply means: How does Spring start, commit or rollback JDBC transactions? Does this sound in any way familiar from above?

Here’s the catch: Whereas with plain JDBC you only have one way (setAutocommit(false)) to manage transactions, Spring offers you many different, more convenient ways to achieve the same.

How to use Spring’s Programmatic Transaction Management?

The first, but rather sparingly used way to define transactions in Spring is programmatically: Either through a TransactionTemplate or directly through the PlatformTransactionManager. Code-wise, it looks like this:

Compared with the plain JDBC example :

You do not have to mess with opening or closing database connections yourself (try-finally). Instead you use Transaction Callbacks .

You also do not have to catch SQLExceptions, as Spring converts these exceptions to runtime exceptions for you.

And you have better integration into the Spring ecosystem. TransactionTemplate will use a TransactionManager internally, which will use a data source. All are beans that you have to specify in your Spring context configuration, but then don’t have to worry about anymore later on.

While this counts as a minor improvement, programmatic transaction management is not what Spring’s transaction framework mainly is about. Instead, it’s all about declarative transaction management . Let’s find out what that is.

How to use Spring’s XML Declarative Transaction Management?

Back in the day, when XML configuration was the norm for Spring projects, you could configure transactions directly in XML. Apart from a couple of legacy, enterprise projects, you won’t find this approach anymore in the wild, as it has been superseded with the much simpler @Transactional annotation.

We will not go into detail on XML configuration in this guide, but you can use this example as a starting point to dive deeper into it - if needed (taken straight from the official Spring documentation ):

You are specifying an AOP advice (Aspect Oriented Programming) with the above XML block, that you can then apply to your UserService bean like so:

Your UserService bean would then look like this:

From a Java code perspective, this declarative transaction approach looks a lot simpler than the programmatic approach. But it leads to a lot of complicated, verbose XML, with the pointcut and advisor configurations.

So, this leads to the question: Is there a better way for declarative transaction management instead of XML? Yes, there is: The @Transactional annotation.

How to use Spring’s @Transactional annotation ( Declarative Transaction Management )

Now let’s have a look at what modern Spring transaction management usually looks like:

How is this possible? There is no more XML configuration and there’s also no other code needed. Instead, you now need to do two things:

Make sure that your Spring Configuration is annotated with the @EnableTransactionManagement annotation (In Spring Boot this will be done automatically for you ).

Make sure you specify a transaction manager in your Spring Configuration (this you need to do anyway).

And then Spring is smart enough to transparently handle transactions for you: Any bean’s public method you annotate with the @Transactional annotation, will execute inside a database transaction (note: there are some pitfalls ).

So, to get the @Transactional annotation working, all you need to do is this:

Now, when I say Spring transparently handles transactions for you. What does that really mean ?

Armed with the knowledge from the JDBC transaction example , the @Transactional UserService code above translates (simplified) directly to this:

This is all just standard opening and closing of a JDBC connection. That’s what Spring’s transactional annotation does for you automatically, without you having to write it explicitly.

This is your own code, saving the user through a DAO or something similar.

This example might look a bit magical , but let’s have a look at how Spring inserts this connection code for you.

CGlib & JDK Proxies - @Transactional under the covers

Spring cannot really rewrite your Java class, like I did above, to insert the connection code (unless you are using advanced techniques like bytecode weaving, but we are ignoring that for now).

Your registerUser() method really just calls userDao.save(user), there’s no way to change that on the fly.

But Spring has an advantage. At its core, it is an IoC container. It instantiates a UserService for you and makes sure to autowire that UserService into any other bean that needs a UserService.

Now whenever you are using @Transactional on a bean, Spring uses a tiny trick. It does not just instantiate a UserService, but also a transactional proxy of that UserService.

It does that through a method called proxy-through-subclassing with the help of the Cglib library . There are also other ways to construct proxies (like Dynamic JDK proxies ), but let’s leave it at that for the moment.

Let’s see proxies in action in this picture:

document1

As you can see from that diagram, the proxy has one job.

Opening and closing database connections/transactions.

And then delegating to the real UserService , the one you wrote.

And other beans, like your UserRestController will never know that they are talking to a proxy, and not the real thing.

Have a look at the following source code and tell me what type of UserService Spring automatically constructs, assuming it is marked with @Transactional or has a @Transactional method.

Correct. Spring constructs a dynamic CGLib proxy of your UserService class here that can open and close database transactions for you. You or any other beans won’t even notice that it is not your UserService, but a proxy wrapping your UserService.

  The Confident Spring Professional

If you want to easily get a deep and practical understanding of the entire Spring Ecosystem or simply refresh your Spring knowledge: I have written a course for you.

Interested in trying out the full first module?

For what do you need a Transaction Manager (like PlatformTransactionManager)?

Now there’s only one crucial piece of information missing, even though we have mentioned it a couple of times already.

Your UserService gets proxied on the fly, and the proxy manages transactions for you. But it is not the proxy itself handling all this transactional state (open, commit, close), the proxy delegates that work to a transaction manager .

Spring offers you a PlatformTransactionManager / TransactionManager interface, which, by default, comes with a couple of handy implementations. One of them is the datasource transaction manager.

It does exactly what you did so far to manage transactions, but first, let’s look at the needed Spring configuration:

You create a database-specific or connection-pool specific datasource here. MySQL is being used for this example.

Here, you create your transaction manager, which needs a data source to be able to manage transactions.

Simple as. All transaction managers then have methods like "doBegin" (for starting a transaction) or "doCommit", which look like this - taken straight from Spring’s source code and simplified a bit:

So, the datasource transaction manager uses exactly the same code that you saw in the JDBC section, when managing transactions.

With this in mind, let’s extend our picture from above:

document2

To sum things up:

If Spring detects the @Transactional annotation on a bean, it creates a dynamic proxy of that bean.

The proxy has access to a transaction manager and will ask it to open and close transactions / connections.

The transaction manager itself will simply do what you did in the plain Java section: Manage a good, old JDBC connection.

What is the difference between physical and logical transactions?

Imagine the following two transactional classes.

UserService has a transactional invoice() method. Which calls another transactional method, createPdf() on the InvoiceService.

Now in terms of database transactions, this should really just be one database transaction. (Remember: getConnection(). setAutocommit(false). commit(). ) Spring calls this physical transaction , even though this might sound a bit confusing at first.

From Spring’s side however, there’s two logical transactions happening: First in UserService, the other one in InvoiceService. Spring has to be smart enough to know that both @Transactional methods, should use the same underlying, physical database transaction.

How would things be different, with the following change to InvoiceService?

Changing the propagation mode to requires_new is telling Spring that createPDF() needs to execute in its own transaction, independent of any other, already existing transaction. Thinking back to the plain Java section of this guide, did you see a way to "split" a transaction in half? Neither did I.

Which basically means your code will open two (physical) connections/transactions to the database. (Again: getConnection() x2. setAutocommit(false) x2. commit() x2 ) Spring now has to be smart enough that the two logical transactional pieces (invoice()/createPdf()) now also map to two different, physical database transactions.

So, to sum things up:

Physical Transactions: Are your actual JDBC transactions.

Logical Transactions: Are the (potentially nested) @Transactional-annotated (Spring) methods.

This leads us to covering propagation modes in more detail.

What are @Transactional Propagation Levels used for?

When looking at the Spring source code, you’ll find a variety of propagation levels or modes that you can plug into the @Transactional method.

The full list:

REQUIRES_NEW

NOT_SUPPORTED

In the plain Java section, I showed you everything that JDBC can do when it comes to transactions. Take a minute to think about what every single Spring propagation mode at the end REALLY does to your datasource or rather, your JDBC connection.

Then have a look at the following answers.

Required (default) : My method needs a transaction, either open one for me or use an existing one → getConnection(). setAutocommit(false). commit() .

Supports : I don’t really care if a transaction is open or not, i can work either way → nothing to do with JDBC

Mandatory : I’m not going to open up a transaction myself, but I’m going to cry if no one else opened one up → nothing to do with JDBC

Require_new: I want my completely own transaction → getConnection(). setAutocommit(false). commit() .

Not_Supported: I really don’t like transactions, I will even try and suspend a current, running transaction → nothing to do with JDBC

Never: I’m going to cry if someone else started up a transaction → nothing to do with JDBC

Nested: It sounds so complicated, but we are just talking savepoints! → connection.setSavepoint()

As you can see, most propagation modes really have nothing to do with the database or JDBC, but more with how you structure your program with Spring and how/when/where Spring expects transactions to be there.

Look at this example:

In this case, Spring will expect a transaction to be open, whenever you call myMethod() of the UserService class. It does not open one itself, instead, if you call that method without a pre-existing transaction, Spring will throw an exception. Keep this in mind as additional points for "logical transaction handling".

What are @Transactional Isolation Levels used for?

This is almost a trick question at this point, but what happens when you configure the @Transactional annotation like so?

Yes, it does simply lead to this:

Database isolation levels are, however, a complex topic, and you should take some time to fully grasp them. A good start is the official Postgres Documentation and their section on isolation levels .

Also note, that when it comes to switching isolation levels during a transaction, you must make sure to consult with your JDBC driver/database to understand which scenarios are supported and which not.

The most common @Transactional pitfall

There is one pitfall that Spring beginners usually run into. Have a look at the following code:

You have a UserService class with a transactional invoice method. Which calls createPDF(), which is also transactional.

How many physical transactions would you expect to be open, once someone calls invoice()?

Nope, the answer is not two, but one. Why?

Let’s go back to the proxies' section of this guide. Spring creates that transactional UserService proxy for you, but once you are inside the UserService class and call other inner methods, there is no more proxy involved. This means, no new transaction for you.

Let’s have a look at it with a picture:

document3

There’s some tricks (like self-injection ), which you can use to get around this limitation. But the main takeaway is: always keep the proxy transaction boundaries in mind.

How to use @Transactional with Spring Boot or Spring MVC

So far, we have only talked about plain, core Spring. But what about Spring Boot? Or Spring Web MVC? Do they handle transactions any differently?

The short answer is: No.

With either frameworks (or rather: all frameworks in the Spring ecosystem), you will always use the @Transactional annotation, combined with a transaction manager and the @EnableTransactionManagement annotation. There is no other way.

The only difference with Spring Boot is, however, that it automatically sets the @EnableTransactionManagement annotation and creates a PlatformTransactionManager for you - with its JDBC auto-configurations. Learn more about auto-configurations here .

How Spring handles rollbacks (and default rollback policies)

The section on Spring rollbacks will be handled in the next revision of this guide.

How Spring and JPA / Hibernate Transaction Management works

The goal: syncing spring’s @transactional and hibernate / jpa.

At some point, you will want your Spring application to integrate with another database library, such as Hibernate (a popular JPA-implementation) or Jooq etc.

Let’s take plain Hibernate as an example (note: it does not matter if you are using Hibernate directly,or Hibernate via JPA).

Rewriting the UserService from before to Hibernate would look like this:

This is a plain, old Hibernate SessionFactory, the entry-point for all Hibernate queries.

Manually managing sessions (read: database connections) and transactions with Hibernate’s API.

There is one huge problem with the above code, however:

Hibernate would not know about Spring’s @Transactional annotation.

Spring’s @Transactional would not know anything about Hibernate’s transaction.

But we’d actually love for Spring and Hibernate to integrate seamlessly, meaning that they know about each others' transactions.

In plain code:

The same SessionFactory as before

But no more manual state management. Instead, getCurrentSession() and @Transactional are in sync .

How to get there?

Using the HibernateTransactionManager

There is a very simple fix for this integration problem:

Instead of using a DataSourcePlatformTransactionManager in your Spring configuration, you will be using a HibernateTransactionManager (if using plain Hibernate) or JpaTransactionManager (if using Hibernate through JPA).

The specialized HibernateTransactionManager will make sure to:

Manage transactions through Hibernate, i.e. the SessionFactory.

Be smart enough to allow Spring to use that very same transaction in non-Hibernate, i.e. @Transactional Spring code.

As always, a picture might be simpler to understand (though note, the flow between the proxy and real service is only conceptually right and oversimplified).

document4

That is, in a nutshell, how you integrate Spring and Hibernate.

For other integrations or a more in-depth understanding, it helps to have a quick look at all possible PlatformTransactionManager implementations that Spring offers.

By now, you should have a pretty good overview of how transaction management works with the Spring framework and how it also applies to other Spring libraries like Spring Boot or Spring WebMVC. The biggest takeaway should be, that it does not matter which framework you are using in the end, it is all about the JDBC basics.

Get them right (Remember: getConnection(). setAutocommit(false). commit(). ) and you will have a much easier understanding of what happens later on in your complex, enterprise application.

Thanks for reading.

Acknowledgements

Thanks to Andreas Eisele for feedback on the early versions of this guide. Thanks to Ben Horsfield for coming up with much-needed Javascript snippets to enhance this guide.

There's more where that came from

I'll send you an update when I publish new guides. Absolutely no spam, ever. Unsubscribe anytime.

the @transactional annotation

let mut author = ?

I'm @MarcoBehler and I share everything I know about making awesome software through my guides , screencasts , talks and courses .

Follow me on Twitter to find out what I'm currently working on.

DZone

  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
  • Manage My Drafts

Data Engineering: Work with DBs? Build data pipelines? Or maybe you're exploring AI-driven data capabilities? We want to hear your insights.

Modern API Management : Dive into APIs’ growing influence across domains, prevalent paradigms, microservices, the role AI plays, and more.

Programming in Python: Dive into the Python ecosystem to learn about popular libraries, tools, modules, and more.

PostgreSQL: Learn about the open-source RDBMS' advanced capabilities, core components, common commands and functions, and general DBA tasks.

  • Spring Boot: How To Use Java Persistence Query Language (JPQL)
  • Understanding Polyglot Persistence
  • Mastering Java Persistence: Best Practices for Cloud-Native Applications and Modernization
  • Mastering Persistence: Why the Persistence Layer Is Crucial for Modern Java Applications
  • KEDA: Kubernetes Event Driven Auto-Scaling in Azure Kubernetes Services (AKS)
  • Using Spring AI With AI/LLMs to Query Relational Databases
  • Dynamic Query Building Spring Boot With JPA Criteria Queries
  • Revolutionizing Machine Learning Pipelines: Google Cloud MLOps for Continuous Integration and Deployment
  • Data Engineering

How Does Spring @Transactional Really Work?

Wondering how spring @transactional works learn about what's really going on..

Vasco Cavalheiro user avatar

Join the DZone community and get the full member experience.

In this post we will do a deep dive into Spring transaction management. We will go over on how does @Transactional really work under the hood. Other upcoming posts will include:

  • how to use features like propagation and isolation
  • what are the main pitfalls and how to avoid them

JPA and Transaction Management

It's important to notice that JPA on itself does not provide any type of declarative transaction management. When using JPA outside of a dependency injection container, transactions need to be handled programatically by the developer:

This way of managing transactions makes the scope of the transaction very clear in the code, but it has several disavantages:

  • it's repetitive and error prone
  • any error can have a very high impact
  • errors are hard to debug and reproduce
  • this decreases the readability of the code base
  • What if this method calls another transactional method?

Using Spring @Transactional

With Spring  @Transactional , the above code gets reduced to simply this:

This is much more convenient and readable, and is currently the recommended way to handle transactions in Spring.

By using  @Transactional , many important aspects such as transaction propagation are handled automatically. In this case if another transactional method is called by  businessLogic() , that method will have the option of joining the ongoing transaction.

One potential downside is that this powerful mechanism hides what is going on under the hood, making it hard to debug when things don't work.

What does  @Transactional mean?

One of the key points about  @Transactional is that there are two separate concepts to consider, each with it's own scope and life cycle:

  • the persistence context
  • the database transaction

The transactional annotation itself defines the scope of a single database transaction. The database transaction happens inside the scope of a persistence context .

The persistence context is in JPA the  EntityManager , implemented internally using an Hibernate  Session (when using Hibernate as the persistence provider).

The persistence context is just a synchronizer object that tracks the state of a limited set of Java objects and makes sure that changes on those objects are eventually persisted back into the database.

This is a very different notion than the one of a database transaction. One Entity Manager  can be used across several database transactions , and it actually often is.

When does an EntityManager span multiple database transactions?

The most frequent case is when the application is using the Open Session In View pattern to deal with lazy initialization exceptions, see this previous blog post for it's pros and cons.

In such case the queries that run in the view layer are in separate database transactions than the one used for the business logic, but they are made via the same entity manager.

Another case is when the persistence context is marked by the developer as  PersistenceContextType.EXTENDED , which means that it can survive multiple requests.

What defines the EntityManager vs Transaction relation?

This is actually a choice of the application developer, but the most frequent way to use the JPA Entity Manager is with the  "Entity Manager per application transaction" pattern. This is the most common way to inject an entity manager:

Here we are by default in "Entity Manager per transaction" mode. In this mode, if we use this Entity Manager inside a  @Transactional method, then the method will run in a single database transaction.

How does @PersistenceContext work?

One question that comes to mind is, how can  @PersistenceContext inject an entity manager only once at container startup time, given that entity managers are so short lived, and that there are usually multiple per request.

The answer is that it can't:  EntityManager is an interface, and what gets injected in the spring bean is not the entity manager itself but  a context aware proxy that will delegate to a concrete entity manager at runtime.

Usually the concrete class used for the proxy is  SharedEntityManagerInvocationHandler , this can be confirmed with the help a debugger.

How does @Transactional work then?

The persistence context proxy that implements  EntityManager is not the only component needed for making declarative transaction management work. Actually three separate components are needed:

  • The EntityManager Proxy itself

The Transactional Aspect

The transaction manager.

Let's go over each one and see how they interact.

The Transactional Aspect is an 'around' aspect that gets called both before and after the annotated business method. The concrete class for implementing the aspect is  TransactionInterceptor .

The Transactional Aspect has two main responsibilities:

  • At the 'before' moment, the aspect provides a hook point for determining if the business method about to be called should run in the scope of an ongoing database transaction, or if a new separate transaction should be started.
  • At the 'after' moment, the aspect needs to decide if the transaction should be committed, rolled back or left running.

At the 'before' moment the Transactional Aspect itself does not contain any decision logic, the decision to start a new transaction if needed is delegated to the Transaction Manager.

The transaction manager needs to provide an answer to two questions:

  • should a new Entity Manager be created?
  • should a new database transaction be started?

This needs to be decided at the moment the Transactional Aspect 'before' logic is called. The transaction manager will decide based on:

  • the fact that one transaction is already ongoing or not
  • the propagation attribute of the transactional method (for example  REQUIRES_NEW always starts a new transaction)

If the transaction manager decides to create a new transaction, then it will:

  • create a new entity manager
  • bind the entity manager to the current thread
  • grab a connection from the DB connection pool
  • bind the connection to the current thread

The entity manager and the connection are both bound to the current thread using  ThreadLocal variables.

They are stored in the thread while the transaction is running, and it's up to the Transaction Manager to clean them up when no longer needed.

Any parts of the program that need the current entity manager or connection can retrieve them from the thread. One program component that does exactly that is the EntityManager proxy.

The EntityManager proxy

The EntityManager proxy (that we have introduced before) is the last piece of the puzzle. When the business method calls for example  entityManager.persist() , this call is not invoking the entity manager directly.

Instead the business method calls the proxy, which retrieves the current entity manager from the thread, where the Transaction Manager put it.

Knowing now what are the moving parts of the  @Transactional mechanism, let's go over the usual Spring configuration needed to make this work.

Putting It All Together

Let's go over how to setup the three components needed to make the transactional annotation work correctly. We start by defining the entity manager factory.

This will allow the injection of Entity Manager proxies via the persistence context annotation:

The next step is to configure the Transaction Manager and to apply the Transactional Aspect in  @Transactional annotated classes:

The annotation  @EnableTransactionManagement tells Spring that classes with the  @Transactional annotation should be wrapped with the Transactional Aspect. With this the  @Transactional is now ready to be used.

The Spring declarative transaction management mechanism is very powerful, but it can be misused or wrongly configured easily.

Understanding how it works internally is helpful when troubleshooting situations when the mechanism is not at all working or is working in an unexpected way.

The most important thing to bear in mind is that there are really two concepts to take into account: the database transaction and the persistence context, each with it's own not readily apparent life cycle.

A future post will go over the most frequent pitfalls of the transactional annotation and how to avoid them.

Published at DZone with permission of Vasco Cavalheiro , DZone MVB . See the original article here.

Opinions expressed by DZone contributors are their own.

Partner Resources

  • About DZone
  • Send feedback
  • Community research
  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone
  • Terms of Service
  • Privacy Policy
  • 3343 Perimeter Hill Drive
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • Spring's transaction management with the @Transactional annotation

Spring Framework

  • Profiling a Spring Boot application with Pyroscope

Spring Boot Rest APIs with PostgreSQL (Spring Boot + Rest APIs)

Dockerize spring boot app and push image to dockerhub (spring boot + dockerhub).

  • Spring Reactive with PostgreSQL (Spring Boot WebFlux + PostgreSQL)
  • Spring Data Redis with RedisTemplate and CrudRepository
  • Sending Emails in Spring Boot via SMTP
  • Securing Server-to-Server Communication with "Spring Boot" & "OAuth 2"
  • Spring Boot, Thymeleaf Hello World (Spring Boot + Thymeleaf + JS/CSS)
  • Caching in Spring Boot (@Cacheable, @CacheEvict & @CachePut)
  • Spring Boot Login/Logout (Spring Security + MySql + Thymeleaf)

Mar 31, 2024

What is a database transaction?

A database transaction is any operation that is treated as a single unit of work that either completes fully or does not complete at all and leaves the storage system in a consistent state.

Transactions can impact a single record or multiple records.

A.C.I.D. properties

ACID is an acronym that stands for atomicity, consistency, isolation, and durability .

ACID properties ensure that a database transaction (a set of read, write, update, or delete operations) leaves the database in a consistent state even in the event of unexpected errors.

1) Atomicity

Atomicity guarantees that all the commands in a transaction (to read, write, update, or delete data) are treated as a single unit and either succeed or fail together.

The transaction would have either completed successfully or been rolled back if any part of it failed.

2) Consistency

Consistency guarantees that the data is in a consistent state when a transaction starts and when it ends.

If the data gets into an illegal state, the whole transaction fails.

3) Isolation

Isolation ensures that the intermediate state of a transaction is invisible to other transactions.

As a result, transactions that run concurrently don't interfere with each other.

4) Durability

Durability guarantees that once the transaction commit and changes are written to the database, they will persist even in the case of system failures like crashes or power outages.

As a result, the transaction's modifications are never undone.

Spring Transaction Management

Spring transaction management simply means: How does Spring start, commit, or rollback JDBC transactions.

Spring provides both declarative (@Transactional) and programmatic (using a TransactionTemplate or PlatformTransactionManager) transaction management, and developers can choose based on the requirement.

Declarative transaction management is easier and more suitable in most cases, but in some cases, you want fine-grain control, and you can use programmatic transaction management.

In order to support transactions in a spring project, you need to add @EnableTransactionManagement to a @Configuration class.

However, if we're using a Spring Boot project and have spring-data-* or spring-tx dependencies on the classpath, then transaction management will be enabled by default.

The @Transactional Annotation

Any bean or public method annotated with the @Transactional annotation makes sure that the methods will be executed inside a database transaction.

The @Transactional annotation should be used in the service layer because it is this layer's responsibility to define the transaction boundaries.

The modern Spring approach to transaction management is typically as follows:

That's it! No configuration, no XML, and no code are needed.

How does the @Transactional annotation work ?

Spring creates dynamic proxies for classes that declare @Transactional on the class itself or on methods.

It does that through a method called proxy-through-subclassing with the help of the Cglib library .

It is also worth noting that the proxy itself does not handle these transactional states (open, commit, close); the proxy delegated this work to a transaction manager.

The proxy has access to a transaction manager and can ask it to open and close transactions and connections.

Spring offers a PlatformTransactionManager (extends TransactionManager) interface, which, by default, comes with a couple of handy implementations. One of them is the DataSourceTransactionManager.

As Spring wraps the bean in the proxy, only calls from "outside" the bean are intercepted. That means, any self-invocation calls will not start any transaction , even if the method has the @Transactional annotation.

Moreover, only public methods should be annotated with @Transactional. Methods of any other visibility will silently ignore the annotation, as these are not proxying.

The same is true for other annotations, such as @Cacheable.

Transaction Rollback

By default, only RuntimeException and Error trigger a rollback. A checked exception does not trigger a rollback of the transaction.

The @Transactional annotation, on the other hand, supports rollbackFor or rollbackForClassName attributes for rolling back transactions, as well as noRollbackFor or noRollbackForClassName attributes for avoiding rollback.

The @Transactional annotation attributes

The @Transactional annotation provides the following attributes:

1) Propagation

The "propagation" attribute defines how the transaction boundaries propagate to other methods that will be called either directly or indirectly from within the annotated block.

There are a variety of propagation modes that can be plugged into the @Transactional method.

2) ReadOnly

The "readOnly" attribute defines if the current transaction is read-only or read-write.

It's a good practise to set the readOnly attribute to true at the class level and override it on a per-method basis for the methods that need to write to the database.

3) RollbackFor and RollbackForClassName

The "rollbackFor" and "rollbackForClassName" attributes define one or more Throwable classes for which the current transaction will be rolled back.

4) NoRollbackFor and NoRollbackForClassName

The "noRollbackFor" and "noRollbackForClassName" define one or more Throwable classes for which the current transaction will not be rolled back.

5) Isolation

The "isolation" attribute describes how changes applied by concurrent transactions are visible to each other.

Source Code: GitHub

avatar

NK Chauhan is a Principal Software Engineer with one of the biggest E Commerce company in the World.

Chauhan has around 12 Yrs of experience with a focus on JVM based technologies and Big Data.

His hobbies include playing Cricket, Video Games and hanging with friends.

Microservices

Java concurrency.

  • ALL TUTORIALS
  • SPRING BOOT

Spring @Transactional Annotation

the @transactional annotation

Technologies Used

@transactional attributes, transaction manager in xml configuration, transaction manager in @configuration class, using @transactional, download source code.

  • @ContextConfiguration Example in Spring Test
  • @SpyBean Example in Spring Test
  • Spring RestTemplate.exchange()
  • @TestPropertySource Example in Spring Test
  • Spring RestTemplate.getForObject()
  • @ActiveProfiles Example in Spring Test
  • Spring RestTemplate.postForEntity()
  • Spring Component Scan Include and Exclude Filter Example
  • Spring Data MongoRepository Update
  • Spring RestTemplate.getForEntity()
  • Spring RestTemplate.postForObject()
  • Spring JdbcTemplate.queryForList()
  • @PreAuthorize and @PostAuthorize in Spring Security
  • Spring Batch + H2 Database Example
  • Spring @JmsListener Example
  • Spring @Value Default Value
  • Spring Data MongoTemplate Example
  • Spring Boot SOAP Web Service Example
  • Spring Boot REST Example
  • Spring Boot CrudRepository Example

ARVIND RAI

©2024 concretepage.com | Privacy Policy | Contact Us

JavaTechOnline

Making java easy to learn, spring transactional example – @transactional annotation.

  • Spring Boot

Last Updated on February 16th, 2024

Spring Transaction Annotations With Examples: Spring Transactional Example

In this article, we will discuss on ‘Spring Transaction Annotations With Examples: Spring Transactional Example’. Obviously, all Spring transactions related annotations will also work with a Spring Boot Application. These annotations play a very important role while creating a web application in Spring Boot. If you want to learn all annotations which are generally used in a Spring Boot Project, kindly visit our article ‘ Spring Boot Annotations with Examples ‘. Let’s discuss about ‘Spring Transactional Example’ here only.

First of all, let’s discuss some fundamentals on the term Transaction, and then move ahead to ‘Spring Transaction Annotations With Examples’.

Table of Contents

What is a Transaction?

Transactions regulate the modifications that we execute in one or more software systems. These software systems can be databases, message brokers etc. The primary intention of a transaction is to offer ACID characteristics to allow the consistency and validity of our data. ACID is an acronym that stands for atomicity, consistency, isolation, and durability.

Atomicity works on ‘all or nothing’ principle. Either all operations carried out within the transaction get executed or none of them. In simple words, if your transaction committed successfully, you can be sure that all operations got performed. It also allows you to terminate a transaction and roll back all operations if an error occurs in any one of the operation.

C onsistency 

The consistency characteristic ensures that your transaction takes a system from one consistent state to another consistent state. That means that either all operations were rolled back and the data was set back to the state you started with or the changed data passed all consistency checks. In a relational database, that means that the modified data needs to pass all constraint checks, like foreign key or unique constraints, defined in your database.

Isolation  

Isolation means that changes that you perform within a transaction are not visible to any other transactions until you commit them successfully.

Durability ensures that your committed changes get persisted.

Relational databases support ACID transactions, and the JDBC specification allows you to control them. Spring provides annotations and different transaction managers to make it easier to use.

There are two ways to manage transactions: Programmatic and Declarative.

Programmatic vs. Declarative Transaction Management

Spring supports two types of transaction management −

Programmatic Transaction Management

In Programmatic transaction management, we have to manage the transaction with the help of programming. It gives us extreme flexibility, but it is tough to maintain.

Declarative Transaction Management

In declarative transaction management, we separate transaction management from the business code. We only use annotations or XML-based configuration to manage the transactions.

Generally, declarative transaction management is preferred over programmatic transaction management. However, declarative transaction management is less flexible than programmatic transaction management. But as a kind of crosscutting concern, declarative transaction management can be modularized with the help of AOP approach. Spring framework also supports declarative transaction management through its Spring AOP module.

Spring Transactional Example

There are two most commonly used annotations in Transaction Management: @EnableTransactionManagement and @Transactional. Let’s discuss about them with examples one by one.

@EnableTransactionManagement 

Spring Transaction support is not enabled by default. Therefore, we use the @EnableTransactionManagement annotation in a @Configuratio n annotated class to enable Transaction related support. It is similar to the support found in Spring’s <tx:*> XML namespace . However, if we are on a Spring Boot Project and already have Spring-data-* or Spring-transaction related dependencies on the classpath, then all the features of this annotation will be available by default. For example, below code demonstrates the feature:

In the above code, @EnableTransactionManagement is responsible for registering the necessary Spring components that enable annotation-driven transaction management.

@Transactional

We can annotate a class or method with @Transactional . We use the @Transactional annotation to separate transaction management code from the code that incorporates business logic. Let’s understand it with the help of an example. To illustrate, let’s assume that we have to develop a money transfer business logic in a Banking application. Then we will write code something like below:

Now, If we use @Transactional annotation, our code will look like below:

This is the magic of @Transactional . You saw how @Transactional has separated the transaction management code from the actual business logic code.

Guidelines to Use @Transactional

1) Make sure to import correct package while applying @Transactional annotation. It comes under package:

On the other hand, Spring also provides support for @Transaction in the context of JPA. The @Transaction for JPA comes under package:

Both of them is used to tell container that the method is transactional. Hence, take extra care before importing the package that which one is applicable in your context.

2) We can apply @Transactional at class, interface or method level, but it is not recommended to use it at an interface. However, it is acceptable in cases such as @Repository with Spring Data.

3) When @Transactional annotation is declared at class level, it applies to all public methods of the declaring class by default. However, if we put the annotation on a private or protected method, Spring will ignore it without an error.

4) The @Transactional annotation does not apply to inherited methods of its ancestor classes. To make them transactional, we need to locally redeclare those methods in this class or its subclasses.

5) While applying @Transactional at the method level, make sure that the method is not already a transactional method. For example, if methods in your service class are internally using JpaRepository methods, then it is not required to apply @Transactional at your service class methods. This is because methods provided by JpaRepository are transactional by default.

Attributes of @Transactional

The @Transactional annotation supports various attributes in order to customize the behavior. Let’s discuss them one by one.

1) isolation

Isolation represents that how changes applied by concurrent transactions are visible to each other. Each isolation level prevents zero or more concurrency side effects on a transaction. Its type is Isolation. It is an enum with five values: DEFAULT, READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE. The default isolation value is Isolation.DEFAULT. For example:

Label is used to describe the transaction. Its type is String [ ]. We can define zero(0) or more transaction descriptions. For example:

3) noRollbackFor  

As the name suggests, it indicates something where no rollback should be applied to the transaction. Actually, it is talking about the exception classes for which there must not be a transaction rollback. It takes zero (0) or more exception Classes, which must be subclasses of Throwable. Remember that the  Throwable class is the superclass of all errors and exceptions in the Java language. Therefore, its type is Class <? extends  Throwable >[ ]. For example:

4) noRollbackForClassName

The purpose of this attribute is the same as for noRollbackFor, but it accepts class names in string form. Hence, its type is String[ ]. In simple words, it takes zero (0) or more exception name patterns, which must be subclasses of Throwable. For example:

5) rollbackFor  

This attribute works as the opposite of the noRollbackFor. Actually, it is talking about the exception classes for which there must be a transaction rollback. It takes zero (0) or more exception Classes, which must be subclasses of Throwable. For example:

6) rollbackForClassName

Similarly, this attribute works as the opposite of the noRollbackForClassName. It accepts zero (0) or more exception name patterns (for exceptions which must be a subclass of Throwable), indicating which exception types must cause a transaction rollback. Its return type is String[ ]. For example:

7) propagation

Propagation defines our business logic’s transaction boundary. Spring manages to start and pause a transaction according to our propagation setting. The Propagation is an enum type and it has values as MANDATORY, NESTED, NEVER, NOT_SUPPORTED, REQUIRED, REQUIRES_NEW and SUPPORTS. For example:

8) readOnly

It represents that the transaction is read-only. The default value is false. If it is true, it means that the transaction is read-only. On the other hand, the default value(false) indicates that the transaction is read-write. Obviously, its type is boolean. For example:

9) timeout  

The timeout attribute indicates the timeout for the transaction in seconds. Its type is int. For example:

10) timeoutString

The timeoutString attribute indicates the timeout for the transaction in seconds, but its type is String. For example:

11) transactionManager  

If transaction manager bean name is transactionManager, then @Transactional annotation picks this name by default. If not, it will match qualifier value or bean name of a specific TransactionManager bean definition. For example:

12) value  

The ‘value’ attribute is the alias for transactionManager attribute.

That’s all about Spring Transactional Example that every developer needs to know. You may also read Spring/Spring Boot related other annotations at Spring Boot Annotations .

the @transactional annotation

  • Persistence

announcement - icon

Azure Spring Apps is a fully managed service from Microsoft (built in collaboration with VMware), focused on building and deploying Spring Boot applications on Azure Cloud without worrying about Kubernetes.

The Enterprise plan comes with some interesting features, such as commercial Spring runtime support, a 99.95% SLA and some deep discounts (up to 47%) when you are ready for production.

>> Learn more and deploy your first Spring Boot app to Azure.

And, you can participate in a very quick (1 minute) paid user research from the Java on Azure product team.

Slow MySQL query performance is all too common. Of course it is. A good way to go is, naturally, a dedicated profiler that actually understands the ins and outs of MySQL.

The Jet Profiler was built for MySQL only , so it can do things like real-time query performance, focus on most used tables or most frequent queries, quickly identify performance issues and basically help you optimize your queries.

Critically, it has very minimal impact on your server's performance, with most of the profiling work done separately - so it needs no server changes, agents or separate services.

Basically, you install the desktop application, connect to your MySQL server , hit the record button, and you'll have results within minutes:

>> Try out the Profiler

Accelerate Your Jakarta EE Development with Payara Server!

With best-in-class guides and documentation, Payara essentially simplifies deployment to diverse infrastructures.

Beyond that, it provides intelligent insights and actions to optimize Jakarta EE applications.

The goal is to apply an opinionated approach to get to what's essential for mission-critical applications - really solid scalability, availability, security, and long-term support:

>> Download and Explore the Guide (to learn more)

A quick guide to materially improve your tests with Junit 5:

Working on getting your persistence layer right with Spring?

Explore the eBook

Do JSON right with Jackson

Download the E-book

Get the most out of the Apache HTTP Client

Get Started with Apache Maven:

Explore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:

>> REST With Spring (new)

Get started with Spring and Spring Boot, through the reference Learn Spring course:

>> LEARN SPRING

Building a REST API with Spring?

The AI Assistant to boost Boost your productivity writing unit tests - Machinet AI .

AI is all the rage these days, but for very good reason. The highly practical coding companion, you'll get the power of AI-assisted coding and automated unit test generation . Machinet's Unit Test AI Agent utilizes your own project context to create meaningful unit tests that intelligently aligns with the behavior of the code. And, the AI Chat crafts code and fixes errors with ease, like a helpful sidekick.

Simplify Your Coding Journey with Machinet AI :

>> Install Machinet AI in your IntelliJ

Get non-trivial analysis (and trivial, too!) suggested right inside your IDE or Git platform so you can code smart, create more value, and stay confident when you push.

Get CodiumAI for free and become part of a community of over 280,000 developers who are already experiencing improved and quicker coding.

Write code that works the way you meant it to:

>> CodiumAI. Meaningful Code Tests for Busy Devs

Looking for the ideal Linux distro for running modern Spring apps in the cloud?

Meet Alpaquita Linux : lightweight, secure, and powerful enough to handle heavy workloads.

This distro is specifically designed for running Java apps . It builds upon Alpine and features significant enhancements to excel in high-density container environments while meeting enterprise-grade security standards.

Specifically, the container image size is ~30% smaller than standard options, and it consumes up to 30% less RAM:

>> Try Alpaquita Containers now.

Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.

I built the security material as two full courses - Core and OAuth , to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project .

You can explore the course here:

>> Learn Spring Security

DbSchema is a super-flexible database designer, which can take you from designing the DB with your team all the way to safely deploying the schema .

The way it does all of that is by using a design model , a database-independent image of the schema, which can be shared in a team using GIT and compared or deployed on to any database.

And, of course, it can be heavily visual, allowing you to interact with the database using diagrams, visually compose queries, explore the data, generate random data, import data or build HTML5 database reports.

>> Take a look at DBSchema

Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot .

Get started with Spring Data JPA through the guided reference course:

>> CHECK OUT THE COURSE

Creating PDFs is actually surprisingly hard. When we first tried, none of the existing PDF libraries met our needs. So we made DocRaptor for ourselves and later launched it as one of the first HTML-to-PDF APIs.

We think DocRaptor is the fastest and most scalable way to make PDFs , especially high-quality or complex PDFs. And as developers ourselves, we love good documentation, no-account trial keys, and an easy setup process.

>> Try DocRaptor's HTML-to-PDF Java Client (No Signup Required)

And, the Enterprise plan comes with some interesting features, such as commercial Spring runtime support, a 99.95% SLA and some deep discounts (up to 47%) when you are ready for production.

You can also ask questions and leave feedback on the Azure Spring Apps GitHub page .

1. Overview

In this tutorial, we’ll discuss the differences between org.springframework.transaction.annotation.Transactional and javax.transaction.Transactional annotations .

We’ll start with an overview of their configuration properties. Then, we’ll discuss what types of components each can be applied to, and in which circumstances we can use one or the other.

2. Configuration Differences

Spring’s Transactional annotation comes with additional configuration compared to its JTA counterpart:

  • Isolation – Spring offers transaction-scoped isolation through the isolation  property; however, in JTA, this feature is available only at a connection level
  • Propagation – available in both libraries, through the propagation property in Spring, and the value property in Java EE; Spring offers Nested as an additional propagation type
  • Read-Only – available only in Spring through the readOnly property
  • Timeout – available only in Spring through the timeout property
  • Rollback – both annotations offer rollback management; JTA provides the rollbackOn and dontRollbackOn  properties, while Spring has rollbackFor and noRollbackFor , plus two additional properties: rollbackForClassName and noRollbackForClassName

2.1. Spring Transactional Annotation Configuration

As an example, let’s use and configure the Spring Transactional annotation on a simple car service:

2.3. JTA Transactional Annotation Configuration

Let’s do the same for a simple rental service using the JTA Transactional annotation:

3. Applicability and Interchangeability

JTA Transactional annotation applies to CDI-managed beans and classes defined as managed beans by the Java EE specification, whereas Spring’s Transactional annotation applies only to Spring beans.

It’s also worth noting that support for JTA 1.2 was introduced in Spring Framework 4.0. Thus, we can use the JTA Transactional annotation in Spring applications . However, the other way around is not possible since we can’t use Spring annotations outside the Spring context.

4. Conclusion

In this tutorial, we discussed the differences between  Transactional annotations from Spring and JTA, and when we can use one or another.

As always, the code from this tutorial is available over on GitHub .

Slow MySQL query performance is all too common. Of course it is.

The Jet Profiler was built entirely for MySQL , so it's fine-tuned for it and does advanced everything with relaly minimal impact and no server changes.

Explore the secure, reliable, and high-performance Test Execution Cloud built for scale. Right in your IDE:

Basically, write code that works the way you meant it to.

AI is all the rage these days, but for very good reason. The highly practical coding companion, you'll get the power of AI-assisted coding and automated unit test generation . Machinet's Unit Test AI Agent utilizes your own project context to create meaningful unit tests that intelligently aligns with the behavior of the code.

Get started with Spring and Spring Boot, through the Learn Spring course:

Get started with spring data jpa through the reference learn spring data jpa course:.

Persistence with SPRING - book cover

Follow the Spring Category

the @transactional annotation

IMAGES

  1. The best way to use the Spring Transactional annotation

    the @transactional annotation

  2. @transactional(readonly = true)- JWord サーチ

    the @transactional annotation

  3. Transactional annotation in Spring

    the @transactional annotation

  4. Lviv JavaClub [Event 157]

    the @transactional annotation

  5. What is @Transactional annotation?

    the @transactional annotation

  6. How to get the current database transaction id

    the @transactional annotation

VIDEO

  1. Lec1-You don’t know Transactional annotation

  2. Are transactional relationships better? @cisterhoodsips ep 5 #dating

  3. TRANSACTIONAL OBEDIENCE

  4. CDS, BOPF, Fiori App on S/4HANA ABAP Programming

  5. Demystify Spring Boot

  6. Stop Trying To Understand

COMMENTS

  1. Using @Transactional :: Spring Framework

    The @Transactional annotation is typically used on methods with public visibility. As of 6.0, protected or package-visible methods can also be made transactional for class-based proxies by default. Note that transactional methods in interface-based proxies must always be public and defined in the proxied interface. For both kinds of proxies, only external method calls coming in through the ...

  2. Transactions with Spring and JPA

    This tutorial will discuss the right way to configure Spring Transactions, how to use the @Transactional annotation and common pitfalls.. For a more in-depth discussion on the core persistence configuration, check out the Spring with JPA tutorial.. Basically, there are two distinct ways to configure Transactions, annotations and AOP, each with its own advantages.

  3. Transaction Management Using @Transactional Annotation

    @Transactional annotation is the metadata used for managing transactions in the Spring Boot application. To configure Spring Transaction, this annotation can be applied at the class level or method level.In an enterprise application, a transaction is a sequence of actions performed by the application that together pipelined to perform a single operation.

  4. The best way to use the Spring Transactional annotation

    The Spring Transactional annotation is very handy when it comes to defining the transaction boundaries of business methods. While the default attribute values were properly chosen, it's good practice to provide both class-level and method-level settings to split use cases between non-transactional, transactional, read-only, and read-write use ...

  5. Spring Transaction Management: @Transactional In-Depth

    If Spring detects the @Transactional annotation on a bean, it creates a dynamic proxy of that bean. The proxy has access to a transaction manager and will ask it to open and close transactions / connections. The transaction manager itself will simply do what you did in the plain Java section: Manage a good, old JDBC connection. ...

  6. How Does Spring @Transactional Really Work?

    The transactional annotation itself defines the scope of a single database transaction. The database transaction happens inside the scope of apersistence context.

  7. Transaction Propagation and Isolation in Spring @Transactional

    It allows us to set propagation, isolation, timeout, read-only, and rollback conditions for our transaction. We can also specify the transaction manager. 2.1. @Transactional Implementation Details. Spring creates a proxy, or manipulates the class byte-code, to manage the creation, commit, and rollback of the transaction.

  8. The @Transactional annotation in Spring Boot

    The @Transactional annotation attributes. The @Transactional annotation provides the following attributes: 1) Propagation. The "propagation" attribute defines how the transaction boundaries propagate to other methods that will be called either directly or indirectly from within the annotated block. There are a variety of propagation modes that ...

  9. Transactional annotation in Spring Framework

    The @Transactional annotation is a powerful tool for simplifying transaction management in Spring applications. By using @Transactional, you can avoid writing boilerplate code to manage ...

  10. Spring @Transactional Annotation

    The @Transactional annotation describes a transaction attribute on an individual method or on a class. The @Transactional belongs to following package. org.springframework.transaction.annotation. 2. When @Transactional annotation is declared at class level, it applies as a default to all methods of the declaring class and its subclasses.

  11. Programmatic Transaction Management in Spring

    Spring's @Transactional annotation provides a nice declarative API to mark transactional boundaries.. Behind the scenes, an aspect takes care of creating and maintaining transactions as they are defined in each occurrence of the @Transactional annotation. This approach makes it easy to decouple our core business logic from cross-cutting concerns such as transaction management.

  12. Best Practices for Using @Transactional in Spring Boot

    Spring Boot's @Transactional annotation provides a mechanism for handling concurrency issues by serializing transactions that modify the same data, preventing multiple threads from modifying the ...

  13. Spring

    When Spring loads your bean definitions, and has been configured to look for @Transactional annotations, it will create these proxy objects around your actual bean. These proxy objects are instances of classes that are auto-generated at runtime. The default behaviour of these proxy objects when a method is invoked is just to invoke the same ...

  14. @Transactional Annotation in Spring Boot

    In Spring Boot, the @Transactional annotation is used to manage transactions for methods in a Spring-managed bean. When a method is annotated with @Transactional, Spring will automatically create a…

  15. Transactionality :: Spring Data JPA

    Repository methods that are backed by transactional repository fragments inherit the transactional attributes from the actual fragment method. ... Note that you must activate <tx:annotation-driven /> or use @EnableTransactionManagement explicitly to get annotation-based configuration of facades to work. This example assumes you use component ...

  16. Spring Transactional Example

    4) The @Transactional annotation does not apply to inherited methods of its ancestor classes. To make them transactional, we need to locally redeclare those methods in this class or its subclasses. 5) While applying @Transactional at the method level, make sure that the method is not already a transactional method.

  17. Transactional Annotations: Spring vs. JTA

    Applicability and Interchangeability. JTA Transactional annotation applies to CDI-managed beans and classes defined as managed beans by the Java EE specification, whereas Spring's Transactional annotation applies only to Spring beans. It's also worth noting that support for JTA 1.2 was introduced in Spring Framework 4.0.

  18. Where should I put @Transactional annotation: at an interface

    The Spring team's recommendation is that you only annotate concrete classes with the @Transactional annotation, as opposed to annotating interfaces. You certainly can place the @Transactional annotation on an interface (or an interface method), but this will only work as you would expect it to if you are using interface-based proxies.

  19. Spring @transactional annotation usage

    Spring recommends that you only annotate concrete classes (and methods of concrete classes) with the @Transactional annotation, as opposed to annotating interfaces. You certainly can place the @Transactional annotation on an interface (or an interface method), but this works only as you would expect it to if you are using interface-based proxies.