it-swarm.com.de

@Transactional-Methode Aufrufen einer anderen Methode ohne @Transactional-Annotation?

Ich habe eine Methode in einer Service-Klasse gesehen, die als @Transactional Markiert war, aber es wurden auch einige andere Methoden in derselben Klasse aufgerufen, die nicht als @Transactional Markiert waren.

Bedeutet dies, dass der Aufruf separater Methoden dazu führt, dass die Anwendung separate Verbindungen zur Datenbank öffnet oder die übergeordnete Transaktion usw. anhält?

Was ist das Standardverhalten für eine Methode ohne Anmerkungen, die von einer anderen Methode mit der Anmerkung @Transactional Aufgerufen wird?

65
goe

Wenn Sie innerhalb eines Transaktionsblocks eine Methode ohne @Transactional Aufrufen, fährt die übergeordnete Transaktion mit der neuen Methode fort. Es wird dieselbe Verbindung von der übergeordneten Methode (mit @Transactional) Verwendet, und jede Ausnahme, die in der aufgerufenen Methode (ohne @Transactional) Verursacht wird, führt zu einem Rollback der Transaktion, wie in der Transaktionsdefinition konfiguriert.

Wenn Sie eine Methode mit einer Annotation @Transactional Aus einer Methode mit @Transactional Innerhalb derselben Instanz aufrufen, hat das Transaktionsverhalten der aufgerufenen Methoden keine Auswirkungen auf die Transaktion. Wenn Sie jedoch eine Methode mit einer Transaktionsdefinition von einer anderen Methode mit einer Transaktionsdefinition aufrufen und diese in unterschiedlichen Instanzen vorliegen, folgt der Code in der aufgerufenen Methode den in der aufgerufenen Methode angegebenen Transaktionsdefinitionen.

Weitere Details finden Sie im Abschnitt Deklarative Transaktionsverwaltung von Frühjahrstransaktionsdokumentation .

Das deklarative Spring-Transaktionsmodell verwendet AOP-Proxy. Daher ist der AOP-Proxy für die Erstellung der Transaktionen verantwortlich. Der AOP-Proxy ist nur aktiv, wenn die Methoden mit in der Instanz von außerhalb der Instanz aufgerufen werden.

91
Arun P Johny
  • Bedeutet das, dass der Aufruf separater Methoden dazu führt, dass die Anwendung separate Verbindungen zur Datenbank öffnet oder die übergeordnete Transaktion usw. anhält?

Das hängt von einem Ausbreitungsnivea ab. Hier sind alle möglichen Ebenen Werte .

Wenn zum Beispiel eine Propagationsebene VERSCHACHTELT ist, wird eine aktuelle Transaktion "angehalten" und eine neue Transaktion erstellt ( Anmerkung: tatsächliche Erstellung von Eine verschachtelte Transaktion funktioniert nur auf bestimmten Transaktionsmanagern)

  • Was ist das Standardverhalten für eine Methode ohne Anmerkungen, die von einer anderen Methode mit @Transactional-Anmerkung aufgerufen wird?

Die Standardausbreitungsstufe (was Sie "Verhalten" nennen) ist ERFORDERLICH . Für den Fall, dass eine "innere" Methode aufgerufen wird, die ein @Transactional Annotation darauf (oder deklarativ über XML abgewickelt), wird es innerhalb der gleichen Transaktion ausgeführt, z. "nichts Neues" wird erstellt.

20
tolitius

@Transactional markiert die Transaktionsgrenze (Anfang/Ende), aber die Transaktion selbst ist an den Thread gebunden. Sobald eine Transaktion gestartet wurde, wird sie über Methodenaufrufe weitergegeben, bis die ursprüngliche Methode zurückgegeben und die Transaktion festgeschrieben/rückgängig gemacht wird.

Wenn eine andere Methode mit einer @ Transactional-Annotation aufgerufen wird, hängt die Weitergabe vom Weitergabeattribut dieser Annotation ab.

8
sourcedelica

Möglicherweise haben Sie die Antwort auf Ihre Frage aus den obigen Antworten erraten. Die innere Methode wirkt sich auf die äußere Methode aus, wenn die innere Methode nicht mit @Transactional kommentiert ist.

Falls die innere Methode auch mit @Transactional mit REQUIRES_NEW Kommentiert ist, geschieht Folgendes.

...
@Autowired
private TestDAO testDAO;

@Autowired
private SomeBean someBean;

@Override
@Transactional(propagation=Propagation.REQUIRED)
public void outerMethod(User user) {
  testDAO.insertUser(user);
  try{
    someBean.innerMethod();
  } catch(RuntimeException e){
    // handle exception
  }
}


@Override
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void innerMethod() {
  throw new RuntimeException("Rollback this transaction!");
}

Die innere Methode ist mit REQUIRES_NEW Kommentiert und löst eine RuntimeException aus, damit ihre Transaktion auf Rollback gesetzt wird, die äußere Transaktion jedoch NICHT AUSWIRKT. Die äußere Transaktion wird PAUSIERT, wenn die innere Transaktion beginnt, und wird dann fortgesetzt, nachdem die innere Transaktion abgeschlossen ist. Sie werden unabhängig voneinander ausgeführt, sodass die äußere Transaktion möglicherweise erfolgreich festgeschrieben wird.

2
saran3h