Spring - @Transactional - What happens in background?

前端 未结 6 473
逝去的感伤
逝去的感伤 2020-11-22 07:17

I want to know what actually happens when you annotate a method with @Transactional? Of course, I know that Spring will wrap that method in a Transaction.

6条回答
  •  情歌与酒
    2020-11-22 07:54

    It may be late but I came across something which explains your concern related to proxy (only 'external' method calls coming in through the proxy will be intercepted) nicely.

    For example, you have a class that looks like this

    @Component("mySubordinate")
    public class CoreBusinessSubordinate {
    
        public void doSomethingBig() {
            System.out.println("I did something small");
        }
    
        public void doSomethingSmall(int x){
            System.out.println("I also do something small but with an int");    
      }
    }
    

    and you have an aspect, that looks like this:

    @Component
    @Aspect
    public class CrossCuttingConcern {
    
        @Before("execution(* com.intertech.CoreBusinessSubordinate.*(..))")
        public void doCrossCutStuff(){
            System.out.println("Doing the cross cutting concern now");
        }
    }
    

    When you execute it like this:

     @Service
    public class CoreBusinessKickOff {
    
        @Autowired
        CoreBusinessSubordinate subordinate;
    
        // getter/setters
    
        public void kickOff() {
           System.out.println("I do something big");
           subordinate.doSomethingBig();
           subordinate.doSomethingSmall(4);
       }
    

    }

    Results of calling kickOff above given code above.

    I do something big
    Doing the cross cutting concern now
    I did something small
    Doing the cross cutting concern now
    I also do something small but with an int
    

    but when you change your code to

    @Component("mySubordinate")
    public class CoreBusinessSubordinate {
    
        public void doSomethingBig() {
            System.out.println("I did something small");
            doSomethingSmall(4);
        }
    
        public void doSomethingSmall(int x){
           System.out.println("I also do something small but with an int");    
       }
    }
    
    
    public void kickOff() {
      System.out.println("I do something big");
       subordinate.doSomethingBig();
       //subordinate.doSomethingSmall(4);
    }
    

    You see, the method internally calls another method so it won't be intercepted and the output would look like this:

    I do something big
    Doing the cross cutting concern now
    I did something small
    I also do something small but with an int
    

    You can by-pass this by doing that

    public void doSomethingBig() {
        System.out.println("I did something small");
        //doSomethingSmall(4);
        ((CoreBusinessSubordinate) AopContext.currentProxy()).doSomethingSmall(4);
    }
    

    Code snippets taken from: https://www.intertech.com/Blog/secrets-of-the-spring-aop-proxy/

提交回复
热议问题