598 Stimmen

Wo gehört die @Transactional-Anmerkung hin?

Sollten Sie die @Transactional im DAO Klassen und/oder deren Methoden oder ist es besser, die Dienstklassen zu annotieren, die die DAO-Objekte verwenden? Oder ist es sinnvoll, beide "Schichten" zu annotieren?

40voto

user2601995 Punkte 5877

Ich stelle die @Transactional über die @Service Ebene und setzen rollbackFor jede Ausnahme und readOnly um die Transaktion weiter zu optimieren.

Standardmäßig @Transactional wird nur suchen nach RuntimeException (Ungeprüfte Ausnahmen), indem Sie Rollback auf Exception.class (Geprüfte Ausnahmen) wird bei jeder Ausnahme ein Rollback durchgeführt.

@Transactional(readOnly = false, rollbackFor = Exception.class)

Voir Geprüfte vs. ungeprüfte Ausnahmen .

0 Stimmen

ReadOnly =false, Eine Nur-Lese-Transaktion kann verwendet werden, wenn Ihr Code Daten liest, aber nicht verändert? Können Sie erklären, warum false? ist es, weil Daten verändert werden?

18voto

lukass77 Punkte 337

Für die Transaktion auf Datenbankebene

meistens habe ich @Transactional in DAO's nur auf Methodenebene, so dass die Konfiguration spezifisch für eine Methode / unter Verwendung von Standard (erforderlich) sein kann

  1. DAO-Methoden, die Daten abrufen (select .. ) - brauchen nicht @Transactional kann dies zu einem gewissen Mehraufwand führen, weil Transaktions-Interceptor / und AOP-Proxy, die ebenfalls ausgeführt werden müssen ausgeführt werden müssen.

  2. DAO-Methoden, die Einfügungen und Aktualisierungen vornehmen, erhalten @Transactional

sehr guter Blog über transaktional

Für die Anwendungsebene -
Ich verwende transaktionale für die Geschäftslogik möchte ich in der Lage sein, Rollback im Falle eines unerwarteten Fehlers

@Transactional(rollbackFor={MyApplicationException.class})
public void myMethod(){

    try {    
        //service logic here     
    } catch(Throwable e) {

        log.error(e)
        throw new MyApplicationException(..);
    }
}

6 Stimmen

+1 sehr schöner Artikel über Transactional in Java

18voto

OkraSala Punkte 183

Oder ist es sinnvoll, beide "Ebenen" zu beschriften? - Ist es nicht sinnvoll, sowohl die Dienstschicht als auch die Dao-Schicht zu annotieren, wenn man sicherstellen will, dass DAO-Methoden immer von einer Dienstschicht aufgerufen (propagiert) werden, deren Propagierung in DAO "obligatorisch" ist. Dies würde eine gewisse Einschränkung für DAO-Methoden von UI-Schicht (oder Controllern) aufgerufen werden. Außerdem wird - insbesondere bei Unit-Tests der DAO-Schicht - durch die Annotation von DAO sichergestellt, dass sie auf transaktionale Funktionalität getestet wird.

0 Stimmen

Würde dies nicht zu einer verschachtelten Transaktion führen? Und all die subtilen Probleme, die damit einhergehen?

11 Stimmen

Nein, in JPA gibt es keine verschachtelten Transaktionen. Sie in beiden zu platzieren, wäre völlig in Ordnung - wenn Sie bereits in einer Transaktion sind, wenn Sie die DAO treffen, würde diese Transaktion fortgesetzt werden.

4 Stimmen

Verschachtelte Transaktionen können auftreten, wenn Sie propagation=Propagation.REQUIRES_NEW . Andernfalls nimmt die DAO in den meisten Fällen, einschließlich propogation=mandatory, einfach an der bestehenden Transaktion teil, die von der Dienstschicht gestartet wurde.

16voto

davidemm Punkte 1929

Außerdem empfiehlt Spring, die Annotation nur für konkrete Klassen und nicht für Schnittstellen zu verwenden.

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

16voto

Harshal Patil Punkte 6457

@Transactional Um alle untrennbaren Vorgänge sollten Anmerkungen gemacht werden. Verwendung von @Transactional Wenn in diesem Fall eine andere Methode von der aktuellen Methode aufgerufen wird, hat diese Methode die Möglichkeit, der laufenden Transaktion beizutreten.

Nehmen wir also ein Beispiel:

Wir haben 2 Modelle, d.h. Country y City . Relationales Mapping von Country y City Modell ist wie ein Country kann mehrere Städte haben, so dass die Zuordnung wie folgt ist,

@OneToMany(fetch = FetchType.LAZY, mappedBy="country")
private Set<City> cities;

Hier Land, das mehreren Städten zugeordnet ist und sie abruft Lazily . Hier kommt also die Rolle der @Transactinal Wenn wir das Objekt "Land" aus der Datenbank abrufen, erhalten wir alle Daten des Objekts "Land", aber nicht den Satz der Städte, da wir die Städte abrufen. LAZILY .

//Without @Transactional
public Country getCountry(){
   Country country = countryRepository.getCountry();
   //After getting Country Object connection between countryRepository and database is Closed 
}

Wenn wir auf den Satz von Städten aus dem Landobjekt zugreifen möchten, erhalten wir Nullwerte in diesem Satz, weil das Objekt des Satzes nur erstellt wird, dieser Satz nicht mit Daten initialisiert wird, um Werte des Satzes zu erhalten, den wir verwenden @Transactional d.h.,

//with @Transactional
@Transactional
public Country getCountry(){
   Country country = countryRepository.getCountry();
   //below when we initialize cities using object country so that directly communicate with database and retrieve all cities from database this happens just because of @Transactinal
   Object object = country.getCities().size();   
}

Also grundsätzlich @Transactional is Service kann mehrere Anrufe in einer einzigen Transaktion tätigen, ohne die Verbindung mit dem Endpunkt zu beenden.

3 Stimmen

Sehr informativ, vielen Dank! Genau das, wonach ich gesucht habe, eine Erklärung dessen, was @Transactional wirklich ist

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