2016-08-02 19 views
0

Ich verwende spring EntityManager und habe eine Anforderung zum Festschreiben von Datensätzen über die Methodenvervollständigung. Das heißt, ich habe zwei Methoden für die Ex ::Spring EntityManager Commit Transaktion als Methode wird abgeschlossen

@Override 
    @Transactional 
    public void upsert(String lastSuccessfullRun) { 
     for(tableData in Tables){ 
     insertIntoDB(tableData); 
     } 
    } 

und das Verfahren insertIntoDB enthält die Buisness-Logik, die tatsächlich funktioniert die Aktualisierung abfragt

@Override 
    @Transactional(propagation=Propagation.REQUIRES_NEW) 
    public void insertIntoDB (String tableData) { 
     em.persist(tableData) 
    } 

Aber das Problem ist, dass das Verfahren nicht begeht wie es für die nächste Schleife in Upsert-Methode zurückkehrt.

Wie kann ich die Methode abschließen?

+0

Nachdem Sie persistiert haben, können Sie versuchen, entityManager.getTransaction(). Commit(); ', auch können Sie in Massen, anstatt für jedes Objekt, wenn es mehrere von ihnen sind. –

+0

@NayanWadekar Da ich Spring EntityManager benutze, kann ich die 'getTransaction()' Methode nicht verwenden, da es eine Ausnahme auslöst, da die Transaktion nicht außerhalb des Spring Containers verwaltet werden kann. –

+0

Sorry, nicht viel in den Frühling scheint dies ähnlich - http://Stackoverflow.com/q/12897882/366964 –

Antwort

2

Überprüfen Sie die documentation.

Methode Sichtbarkeit und @Transactional

Wenn Proxies verwenden, sollten Sie die @Transactional Anmerkung nur auf Verfahren mit öffentlicher Sichtbarkeit gelten. Wenn Sie geschützte, Private oder Package-Visible-Methoden mit der Annotation @Transactional, kommentieren, wird kein Fehler ausgelöst, aber die mit Annotationen versehene Methode zeigt nicht die konfigurierten Transaktionseinstellungen. Erwägen Sie die Verwendung von AspectJ (siehe unten unter ), wenn Sie nicht öffentliche Methoden mit Anmerkungen versehen müssen.

Selbst wenn Ihre Methode public ist, werden Sie es in einem anderen Verfahren in der gleichen Klasse aufrufen, so gehen Sie nicht trugh den Proxy und die @Transactional(propagation=Propagation.REQUIRES_NEW) auf insertIntoDB Methode hat keine Auswirkung.

Versuchen Sie es im AspectJ-Modus, wie in der Dokumentation.

+0

Wenn ich eine innere Klasse verwenden würde, dann würde es funktionieren, ich meine, würde der gleiche Proxy-Mechanismus? –

+0

@Anand j. Kadhi: Nicht sicher ... Du musst es versuchen. –

0

versuchen, wie unten gezeigt werden:

@Override 
    @Transactional(propagation=Propagation.REQUIRES_NEW) 
    public void upsert(String lastSuccessfullRun) { 
     for(tableData in Tables){ 
     insertIntoDB(tableData); 
     } 
    } 



@Override 
    @Transactional(propagation=Propagation.SUPPORTS) 
    public void insertIntoDB (String tableData) { 
     em.persist(tableData) 
    } 

, wenn Sie „Ausbreitung = Propagation.REQUIRES_NEW“ in insertIntoDB Methode verwenden, dann wird es eine neue Transaktion erstellen und sie begehen, wenn insertIntoDB Verfahren abgeschlossen.

0

@Transactional funktioniert nur, wenn Sie die Methode Proxy auslösen, so in Ihrem Fall funktioniert es nicht. Wenn Sie wirklich, dass Ihre Änderungen in der Datenbank reflektiert wollen und in Ihrem PersistenceContext, die mit Ihrer aktiven Transaktion verbunden sind, können Sie

EntityManager.flush(); 

verwenden, aber denken Sie daran, wenn Flush() verwendet die Änderungen an den Daten in der Datenbank reflektiert nach flush, aber es ist immer noch in der Transaktion und kann Rollback und die Transaktion ist immer noch aktiv, aber wenn Sie commit() verwenden, werden die Änderungen in die Datenbank gemacht & Transaktion endet auch dort.