Possiamo semplificare la gestione delle transazioni programmatica con AOP?
-
26-10-2019 - |
Domanda
Ho voluto impostare il transactionManager sulla base di alcuni criteri di ingresso e, quindi, mi sono trasferito da dichiarativa per la gestione delle transazioni a livello di programmazione.
qualcosa di simile
public User saveUser(NewUser newUser){
return transactionTemplate.execute(new TransactionCallback() {
// the code in this method executes in a transactional context
public Object doInTransaction(TransactionStatus status) {
try {
User savedObj = someService.saveUser(newUser);
return savedObj ;
} catch (DataManagerAPIException e) {
throw new RuntimeException(e);
}
}
});
}
Tutto funziona bene, ma avvolgere ogni chiamata di servizio (il nostro limite di transazione è al GWT level.Something servizio al cliente come interfaccia utente -> Client Service -> Servizio -> Dao) con un callback transazione sta facendo il bit di codice di un pasticcio rispetto al @Transactional. Ci può essere un modo più semplice per fare questo? Forse un approccio basato AOP?
Ho provato il seguente
//Wrap every Client service method with a transaction.
@Around("execution(* com.myProject.server.service.*.*(..))")
public void transactionManagerProviderResult(final ProceedingJoinPoint pjp) {
transactionTemplate.execute(new TransactionCallback() {
@Override
public Object doInTransaction(TransactionStatus status) {
try {
Object result = pjp.proceed();
return result ;
} catch (Throwable e) {
e.printStackTrace();
return null;
}
}
});
}
Il codice viene eseguito bene all'interno del contesto transazionale e il 'risultato' contiene il giusto valore (l'utente appena salvata), ma il chiamante del metodo saveUser (strato GWT Widget) ottiene sempre un oggetto nullo. Questo non è un problema con GWT da quando ho provato indipendente GWT anche. Tutto sembra andare bene fino a 'risultato'. Dopo questo l'oggetto è perduto. Quale potrebbe essere il motivo possibile e la soluzione per il problema?
Soluzione
Il chiamante ottiene un oggetto nullo perché non si ritorni nulla dal tuo metodo:
public Object transactionManagerProviderResult(final ProceedingJoinPoint pjp) {
return transactionTemplate.execute(new TransactionCallback() {
// ...
Non è molto chiaro il motivo per cui è necessario farlo da soli invece di lasciare che il supporto @Transactional
Primavera farlo per voi.