Sunday, January 3, 2016

Understanding Spring @Transactional deeply

This post will try to explain the annotation @Transaction in Spring framwork in detail. I will try to answer the following questions:


  1. How can Spring interpret @Transactional?
  2. What will Spring do with @Transactional?
  3. How to use @Transactional correctly?


I. Aspect Oriented Programming (AOP)
Before we dive into inspecting Spring @Transactional annotation I would like to take a look little at AOP. Because Spring uses AspectJ (AspectJ is an aspect-oriented programming (AOP) extension created at PARC for the Java programming language.) to help parsing @Transactional annotation and then opening transaction before the actual code of the annotated method is executed.

Now let's get started with AspectJ


Step 0:
Download and install IDE Spring Tool Suite (STS) 

Step 1:

Open Spring Tool Suite and create an AspectJ project StudyAJ









Step 2:

Create a package and put Java classes, aspect files into it.









Greeting.java
package com.sonand.studyaj;

public class Greeting {
 public void say(String message) {
  System.out.println(message);
 }
 
 public void sayToCustomer(String message) {
  System.out.println(message);
 }
}
This is a simple java class.

GreetingAspect.aj
package com.sonand.studyaj;

public aspect GreetingAspect {
 pointcut callSayGreeting() :
  call(* *.say*(..));
 
 before() : callSayGreeting() {
  System.out.println("Hi!");
 }
 
 after() : callSayGreeting() {
  System.out.println("Thank you!");
 }
}
This is an simple aspect and it includes aspect keyword, not class keyword. I will explain it in detail later.

Main.java
package com.sonand.studyaj;

public class Main {

 public static void main(String[] args) {  
  Greeting gt = new Greeting();
  gt.say("Can I help you?");
  System.out.println("\n---------------------------------------------------");
  gt.sayToCustomer("Are you okay there?");
 }

}

To compile this project, Spring Tool Suite will call to AspectJ compiler for compiling file GreetingAspect.aj automatically. Now let's run it.

Output:
Hi!
Can I help you?
Thank you!

---------------------------------------------------
Hi!
Are you okay there?
Thank you!

From the above output we see that each time main program call a method of Greeting object for outputting a greeting message, other messages are also output right above and right below the greeting message. These additional messages originate from the aspect GreetingAspect. More specifically, these messages originate from advice before() and advice after()


Advice
Advice is a terminology in AOP world and it will execute additional code we added. How is advice kicked in? The answer is: an advice is kicked in when the pointcut attached to it is matched. We go to another terminology pointcut.

Pointcut
A pointcut is a program element that picks out join points and exposes data from the execution context of those join points. Pointcuts are used primarily by advice. They can be composed with boolean operators to build up other pointcuts.In aspect GreetingAspect there is a pointcut with name callSayGreeting() and it is defined:
pointcut callSayGreeting() :
  call(* *.say*(..));
where, pointcut is keyword, callSayGreeting() is pointcut name, call(...) is pointcut type. The part with wildcards "* *.say*(..)" is called jointpoint.

Jointpoint
A jointpoint is one or many points in a program's execution. For example, joinpoint could define call/execute to specific methods in a class.
Here, we defined jointpoint "* *.say*(..)". This jointpoint will match any public/protected method from any class. Method name starts with string "say" and has any parameters.

Put it together: when the main program call a method of Greeting object starting with string "say" the pointcut callSayGreeting() will be matched. Because this pointcut is attached to advices before() and after() these advices will be kicked in respectively. Firstly, the advice before() is executed, then the called method is executed and finally the advice after() is executed. That's all.

Apart from the pointcut call(...) AspectJ also offers other pointcut types. Similarly, AspectJ also offer other advices other than before() and after(). In the next part I will reveal other pointcuts and other advices used by Spring. For more information about AspectJ, please read https://eclipse.org/aspectj/docs.php

No comments: