455 Stimmen

Spring - @Transactional - Was passiert im Hintergrund?

Ich möchte wissen, was eigentlich passiert, wenn man eine Methode mit @Transactional ? Natürlich weiß ich, dass Spring diese Methode in eine Transaktion verpacken wird.

Ich habe jedoch folgende Zweifel:

  1. Ich habe gehört, dass der Frühling eine Proxy-Klasse ? Kann jemand dies genauer erklären Tiefe . Was befindet sich eigentlich in dieser Proxy-Klasse? Was geschieht mit der eigentlichen Klasse? Und wie kann ich die von Spring erstellte Proxy-Klasse sehen?
  2. Ich habe auch in den Spring-Dokumenten gelesen, dass:

Hinweis: Da dieser Mechanismus auf Proxys basiert, nur "externe" Methodenaufrufe, die über den Proxy eingehen, werden abgefangen . Dies bedeutet, dass ein "Selbstaufruf", d. h. eine Methode innerhalb des Zielobjekts, die eine andere Methode des Zielobjekts aufruft, zur Laufzeit nicht zu einer tatsächlichen Transaktion führt, selbst wenn die aufgerufene Methode mit @Transactional !

Source : http://static.springsource.org/spring/docs/2.0.x/reference/transaction.html

Warum fallen nur externe Methodenaufrufe unter Transaktion und nicht die Selbstaufrufmethoden?

9voto

Danyal Sandeelo Punkte 11591

Es mag spät sein, aber ich bin auf etwas gestoßen, das Ihr Anliegen in Bezug auf den Proxy (nur "externe" Methodenaufrufe, die über den Proxy eingehen, werden abgefangen) gut erklärt.

Ein Beispiel: Sie haben eine Klasse, die wie folgt aussieht

@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");    
  }
}

und Sie haben einen Aspekt, der wie folgt aussieht:

@Component
@Aspect
public class CrossCuttingConcern {

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

Wenn Sie es so ausführen:

 @Service
public class CoreBusinessKickOff {

    @Autowired
    CoreBusinessSubordinate subordinate;

    // getter/setters

    public void kickOff() {
       System.out.println("I do something big");
       subordinate.doSomethingBig();
       subordinate.doSomethingSmall(4);
   }

}

Ergebnisse des Aufrufs von kickOff mit dem oben angegebenen Code.

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

aber wenn Sie Ihren Code ändern in

@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);
}

Die Methode ruft intern eine andere Methode auf, so dass sie nicht abgefangen wird und die Ausgabe wie folgt aussehen würde:

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

Sie können dies umgehen, indem Sie Folgendes tun

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

Codeschnipsel entnommen aus: https://www.intertech.com/Blog/secrets-of-the-spring-aop-proxy/

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X