2009-04-30 7 views
1

Nicht sicher, ob "Geltungsbereich" hier der richtige Begriff ist.Soll ich den Umfang von @Transactional minimieren?

Ich verwende Spring für JPA-Transaktionsverwaltung (mit einem Hibernate darunter). Meine Methode Datenbanktransaktion Preform ist privat, aber da Sie nur @Transactional auf einer Klasse oder auf einem public method

Da dieser Mechanismus auf Proxies basiert gesetzt, nur ‚externe‘ Methode aufruft, kommt in durch den Proxy abgefangen werden. Dies bedeutet, dass "Selbstaufruf", d. H. Eine Methode innerhalb des Zielobjekts, die eine andere Methode des Zielobjekts aufruft, selbst dann nicht zu einer tatsächlichen Transaktion führt, wenn die aufgerufene Methode mit @Transactional!

Ich habe den öffentlichen Einstiegspunkt der Klasse als @Transactional gesetzt.

@Transactional 
public void run(parameters) { 
    //First non-database method, takes a decent amount of time 
    Data data = getData(); 
    //Call to database 
    storeData(data); 
} 

private storeData(data) { 
    em.persist(data); 
} 

Ist das eine schlechte Übung? Ist Spring länger offen als nötig? Ich dachte daran, die storeData() -Methode in eine DAO-Klasse zu verschieben und öffentlich zu machen, aber als akademischer Punkt wollte ich wissen, ob die Umgestaltung der Öffentlichkeit einen Leistungsvorteil bringen würde.

+0

Ich habe zwei Antworten hier, dass, wenn ich sie richtig verstehe, gegensätzliche Dinge sagen, kann jemand anderes auf diese Frage einwiegen? –

+0

Die Frage http://stackoverflow.com/questions/1079114 hat eine gewisse Relevanz für diesen. –

Antwort

1

Wenn es große Konflikte in der Datenbank gibt, ist es entscheidend, Transaktionen so klein wie möglich zu halten - viel wichtiger als die Unterscheidung zwischen öffentlich und privat, die per se die Leistung und Skalierbarkeit nicht beeinträchtigen. Also, sei praktisch ...!

+0

Ich denke, Sie haben meine Frage vielleicht falsch verstanden. @Transactional kann nur für eine öffentliche Methode existieren, aber was ich möchte, ist, dass wir versuchen sollten, @Transactional auf Methoden zu beschränken, die ausschließlich Datenbank arbeiten. –

+1

Ich habe es verstanden: Wir sollten Transaktionsbereiche in der Tat so eng wie möglich beschränken, und wenn das bedeutet, einige Dinge öffentlich zu machen, die Sie lieber privat halten wollen, ist das nicht das Ende der Welt. –

1

Der Transaktionsbereich hat keine Auswirkungen, bis der Code etwas ausführt, das mit dem Transaktionskontext interagiert, in diesem Fall die Methode storeData(). Die Tatsache, dass getData() nicht transaktional ist, sollte die Leistung bei der Parallelität Ihres Codes nicht beeinträchtigen, da eine Datenbanksperrung nur stattfindet, wenn storeData() erreicht wird.

+0

Hängt von der Transaktionsisolationsstufe ab. Bei der SERIALIZABLE-Isolierung muss die Datenbank den Status zu Beginn der Transaktion verfolgen, damit Commits von anderen Transaktionen Ihre Lesevorgänge nicht beeinflussen. – andri

+0

@andri, wann beginnt die Transaktion dann? Ich dachte, Skaffman würde sagen, es fängt erst an, wenn der Anruf bei em.persist erfolgt? –

+1

Soweit die Datenbank betroffen ist, beginnt die Transaktion erst, wenn eine Verbindung zur Datenbank hergestellt wird. Wenn dies nicht erfolgt, bis die storeData() -Methode aufgerufen wird, dann beginnt die Transaktion, soweit die Datenbank betroffen ist. Bevor die Verbindung enthalten ist, ist die Datenbank nicht beteiligt und wird nicht informiert. – skaffman

Verwandte Themen