0% found this document useful (0 votes)
2 views

Spring Transaction Handling

This document provides an overview of transaction handling in Spring Boot, explaining how transactional methods work and the role of the @Transactional annotation. It details the configuration options for transaction management, including propagation behaviors and settings for read-only transactions. Additionally, it discusses the differences between Spring's @Transactional and Java's javax.transaction.Transactional annotations, along with best practices for applying transactional behavior in Spring applications.

Uploaded by

R. C.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Spring Transaction Handling

This document provides an overview of transaction handling in Spring Boot, explaining how transactional methods work and the role of the @Transactional annotation. It details the configuration options for transaction management, including propagation behaviors and settings for read-only transactions. Additionally, it discusses the differences between Spring's @Transactional and Java's javax.transaction.Transactional annotations, along with best practices for applying transactional behavior in Spring applications.

Uploaded by

R. C.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 1

JAVA HOME CONTACT US

CODE HOUSE

REST API with Spring Boot | Lesson 9 | Spring


0

Transaction Handling
Share

08 May 2021

Transactional Methods

What happens when a method is transactional?

The method executes inside of a transaction, if anything goes wrong in the middle of the method execution, the
transaction will be rolled back, otherwise, it will be committed.

Transactional Method Example


Let’s say there were 100 comments in a database, and while a method is being executed, 30 of them were
successfully streamed, but then something happens in the middle of it and it could not read from the database
anymore.

If the method runs within a transaction, the whole method will fail instead of returning 30 comments.

That prevents us from getting an incomplete list of comments.

How Spring Transactions Work | What Happens Behind The Scene?

Spring provides comprehensive transaction support, and the following is a very simplified overview of how it
works.

Spring Framework’s transaction support is enabled via AOP proxies. So the caller of the method invokes
the proxy, not the target, and at this point, a transaction is created. Then the target method is invoked,
and on the way back, either the transaction is committed or rolled back.

How To Enable Spring’s Transaction Management

Typically transaction management is enabled using @EnableTransactionManagement annotation or it could also be


done via XML.

We are building a Spring Boot application, so most of the configuration is done for me. because I have spring-data
libraries in the classpath, transaction management is enabled by the framework. So, you don’t have to do anything
to enable transaction management.

In order to apply transaction management, all you have to do is add the @Transactional annotation.

What Is @Transactional Annotation In Spring?

The @Transactional annotation is metadata that specifies that an interface, class, or method must have
transactional semantics. For example, “start a brand new read-only transaction when this method is invoked,
suspending any existing transaction”.

There are quite a few settings that can be applied to this annotation. The following table from the documentation
lists all of them.

@Transactional Settings

Property Type Description

Optional qualifier specifying the


value String
transaction manager to be used.

propagation enum: Propagation Optional propagation setting.

isolation enum: Isolation Optional isolation level.

readOnly boolean Read/write vs. read-only transaction

timeout int (in seconds granularity) Transaction timeout.

Array of Class objects, which must be Optional array of exception classes that
rollbackFor
derived from Throwable. must cause rollback.

Array of class names. Classes must be Optional array of names of exception


rollbackForClassName
derived from Throwable. classes that must cause rollback.

Array of Class objects, which must be Optional array of exception classes that
noRollbackFor
derived from Throwable. must not cause rollback.

Array of String class names, which Optional array of names of exception


noRollbackForClassName
must be derived from Throwable. classes that must not cause rollback.

Defaults Of Some @Transactional Settings

Property Default value

propagation PROPAGATION_REQUIRED

Isolation ISOLATION_DEFAULT

readOnly read/write.

The default timeout of the underlying transaction system, or to none if timeouts are not
timeout
supported.

rollbackFor RuntimeExceptions triggers rollback, and any checked Exceptions do not.

propagation

These are the transaction propagation behaviours defined by the propagation enum. Let’s look at a couple of
them.

REQUIRED - Supports a current transaction, create a new one if none exists. If there is a transaction already
started, then this method will execute within that, otherwise, a new one will be created.

REQUIRES_NEW - Create a new transaction, and suspend the current transaction if one exists.

readOnly

The next attribute I want to look at is readOnly , which is a boolean.

What happens when the read-only attribute is set to true ? Spring doesn’t handle persistence, so it cannot
define exactly what read-only should do. So this is just a hint to the provider which in this case is hibernate.
According to the documentation, if using hibernate as the JPA provider, when readOnly flag is set to true ,
flushMode on the Hibernate session will be set to NEVER, preventing any changes to data.

Following is the excerpt from the spring data documentation which states this.

“It’s definitely reasonable to use transactions for read only queries and we can mark them as such by setting the readOnly flag. This will
not, however, act as check that you do not trigger a manipulating query (although some databases reject INSERT and UPDATE
statements inside a read only transaction). The readOnly flag instead is propagated as hint to the underlying JDBC driver for
performance optimizations. Furthermore, Spring will perform some optimizations on the underlying JPA provider. E.g. when used with
Hibernate the flush mode is set to NEVER when you configure a transaction as readOnly which causes Hibernate to skip dirty checks (a
noticeable improvement on large object trees).” — Spring Documentation

timeout

timeout is the number of seconds before a transaction times out.

javax.transaction.Transactional vs
org.springframework.transaction.annotation.Transactional
Spring transaction management also supports the @Transactional annotation from Java
( javax.transaction.Transactional ) as a drop-in replacement for the @Transactional annotation provided by
Spring. However, it lacks some of the settings available in the one from Spring such as readOnly and timeout
which are quite useful. So I would use Spring’s @Transactional annotation instead of the one from Java.

What Can Be Annotated With @Transactional?


The @Transactional annotation can be placed on interfaces, classes, or both class and interface methods.

“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. The fact that Java annotations are not inherited
from interfaces means that if you are using class-based proxies ( proxy-target-class=”true”) or the weaving-based aspect (
mode=”aspectj”), then the transaction settings are not recognized by the proxying and weaving infrastructure, and the object will not be
wrapped in a transactional proxy, which would be decidedly bad.”
— Spring Documentation

Don’t worry if you are confused with the above excerpt, it’s all explained below. 

Transaction Configuration In Spring

In a typical Spring application, configuration could be done via XML or Java/annotations.

XML Based configuration


When using XML based configurations, the following line in the config file would enable annotation-driven
transaction management.

<!-- enable the configuration of transactional behavior based on annotations -->


<tx:annotation-driven transaction-manager="txManager"/>

Following are the settings or the attributes which can be set on this tag.

transaction-manager
mode
proxy-target-class
order

Java Based configuration


When using java based configuration, @EnableTransactionManagement annotation would be used to provide the
same configuration as above.

It has the following three optional elements.

mode
order
proxyTargetClass

Regardless of the mode of configuration, i.e. either XML or Java based configuration, so long as we have not
specifically set these attributes, the default values apply. So let’s look at each one.

The proxyTargetClass or proxy-target-class


This could be either true or false.

The default value is false. In which case, JDK interface-based proxies are created.

If this attribute is set to true, then CGLIB proxies will be used, which are class-based, and therefore any
@Transactional annotations on interfaces will be ignored.

The mode
There are 2 values that can be applied to the mode attribute. proxy and aspectJ .

The default value of the mode attribute is proxy . It processes annotated beans to be proxied using Spring’s AOP
framework, which would proxy interfaces annotated with @Transactional .

But when the mode is set to aspectJ the interfaces annotated with @Transactional will be ignored.

That’s because,

The aspect that interprets @Transactional annotations is the AnnotationTransactionAspect. When using this aspect, you must annotate
the implementation class (and/or methods within that class), not the interface (if any) that the class implements. AspectJ follows Java’s
rule that annotations on interfaces are not inherited. — Spring Documentation

Keep in mind when using proxy mode which is the default setting.
. only external method calls will be transactional.
even though a method is marked with @Transactional annotation, if it is called within another
method of the same object, it will not have transactional behaviour.

. you should apply the @Transactional annotation only to methods with public visibility.
If you do annotate protected, private or package-visible methods with the @Transactional
annotation, no error is raised, but the annotated method does not exhibit the configured
transactional settings.

So if you want transactional behaviour in either self invocations or non-public methods, consider the use
of aspectJ mode instead of proxy .

What Happens In A Spring Boot Application


In a Spring Boot application, transaction management is enabled by the framework, without having to add the
@EnableTransactionManagement annotation, and the defaults are applied. Hence there is no restriction as to
where to place the @Transactional annotations, but it is safer to follow the recommendation because in case
those need to be changed later on.

I highly recommend reading the documentation for Spring transaction management as we cannot cover
everything here.

Next

 Lesson 10 - Integration Testing Part 2

Copyright © 2021 Javacodehouse.com | All Rights Reserved

You might also like