2016-09-05 2 views
5

Beim Schreiben von Transaktionsmethoden mit @Async ist es nicht möglich, die @Transactional Ausnahmen abzufangen. Wie ObjectOptimisticLockingFailureException, weil sie außerhalb der Methode selbst während zB Transaktion Commit geworfen werden.Wie können Transaktionsausnahmen in @Async abgefangen werden?

Beispiel:

public class UpdateService { 
    @Autowired 
    private CrudRepository<MyEntity> dao; 

    //throws eg ObjectOptimisticLockingFailureException.class, cannot be caught 
    @Async 
    @Transactional 
    public void updateEntity { 
     MyEntity entity = dao.findOne(..); 
     entity.setField(..); 
    } 
} 

Ich weiß, ich @Async Ausnahmen fangen kann im Allgemeinen wie folgt:

@Component 
public class MyHandler extends AsyncConfigurerSupport { 
    @Override 
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { 
     return (ex, method, params) -> { 
      //handle 
     }; 
    } 
} 

Aber ich würde es vorziehen, die gegebene Ausnahme auf eine andere Weise zu behandeln NUR wenn es tritt innerhalb der UpdateService auf.

Frage: Wie kann ich es fangen innerhalb der UpdateService?

Ist die einzige Chance: Erstellen eines zusätzlichen @Service, der die UpdateService umschließt und einen try-catch Block hat? Oder könnte ich es besser machen?

Antwort

1

Sie könnten self-injecting Ihre Bean versuchen, die mit Spring 4.3 arbeiten sollte. Während Self-Injecting in der Regel keine gute Idee ist, kann dies einer der legitimen Anwendungsfälle sein.

@Autowired 
private UpdateService self; 

@Transactional 
public void updateEntity() { 
    MyEntity entity = dao.findOne(..); 
    entity.setField(..); 
} 

@Async 
public void updateEntityAsync(){ 
    try { 
     self.updateEntity(); 
    } catch (Exception e) { 
     // handle exception 
    } 
} 
+0

Wenn dies tatsächlich ein gültiger Anwendungsfall für die Selbstinjektion ist, könnte dies ausreichend sein. Die Frage ist: Ist es? – membersound

+0

@membersound: Meiner Meinung nach ist es gültig. Es ist auch möglich, es zu missbrauchen, so dass Sie mit einer "Gottesklasse" mit 1000 Zeilen enden. Aber Ihre Exception-Behandlung ist spezifisch für diese Klasse, warum nicht in der Klasse. Wenn jemand es für eine schlechte Übung hält, könnten sie hier einen Kommentar hinterlassen ... – user140547

+0

Es funktioniert nicht und scheitert mit: 'Es gibt eine zirkuläre Abhängigkeit zwischen 1 Beans'. Spring-Boot.1.4.0 mit Feder.4.2.3 – membersound

Verwandte Themen