Ho una classe @Service che ha un metodo @Transactional che chiama un altro metodo @Transactional sulla stessa classe. Stavo testando il comportamento del rollback per questo e ho scoperto che non funzionava correttamente. Il codice simile a questa:Spring nested @Transactional method and rollback
@Service
public class DefaulService implements ervice
{
@Transactional
public void methodOne()
{
methodTwo();
//question edited
//this seems to be the problem
this.serviceDAO.executeUpdateOperation();
//test rollback
throw new RuntimeException();
}
@Transactional
public void methodTwo()
{
//DAO stuff
}
}
Dopo l'esecuzione methodOne controllo il database e le modifiche sono lì, anche se il registro mostra "JDBCTransaction - rollback".
Se chiamo methodDue singolarmente e aggiungo un'eccezione alla fine, le modifiche vengono ripristinate correttamente.
C'è un modo per rendere methodOne correttamente le modifiche di rollback che si sono verificate durante la chiamata @Transactional nidificata? Avevo l'impressione che la propagazione predefinita di REQUIRED avrebbe raggiunto questo obiettivo, ma non sembra funzionare. Grazie
UPDATE
Ok, ho appena notato qualcosa di diverso. Proprio prima del lancio dell'eccezione, sto chiamando il dao del servizio e sto eseguendo un aggiornamento manuale tramite 'executeUpdate'. Se commento questa riga, il rollback annidato funziona. Sembra quindi che il problema sia in realtà chiamare DAO ed eseguire query executeUpdate. Ma non dovrebbe funzionare anche all'interno della transazione corrente?
Sei consapevole del fatto che quando si chiama 'methodTwo()' da 'methodOne() 'l'annotazione' @ Transactional' su quella precedente viene ignorata? Vedi il mio [articolo] (http://nurkiewicz.blogspot.com/2011/10/spring-pitfalls-proxying.html) per ulteriori dettagli. Tuttavia questo non causa i tuoi problemi, ma vale la pena di saperlo. –
Sì, ma poiché MethodTwo può essere chiamato in modo indipendente, quindi ha bisogno della propria annotazione per tali casi. In questo momento sono perplesso sul motivo per cui executeUpdate causa il commit della transazione, anche se forse questo è il comportamento predefinito. – JayPea
qual è la propagazione della transazione del servizio a pagamento? È per caso REQUIRES_NEW? – Hendrik