java - Spring UnexpectedRollbackException in nested @Transactional method -
i have dao class (mydao
) marked @transactional
annotaion (on class level) no additional parameters. in dao class have method in case needs throw checked exception , perform transaction rollback. this:
@transactional public class mydao { public void daomethod() throws mycheckedexception() { if (somethingwrong) { transactionaspectsupport.currenttransactionstatus().setrollbackonly(); throw new mycheckedexception("something wrong"); } }
this works fine. however, dao method called service method, marked @transactional:
public class myservice { @autowired private mydao mydao; @transactional public void servicemethod() throws mycheckedexception { mydao.daomethod(); } }
the problem when daomethod()
called servicemethod()
, marks transaction rollback only, unexpectedrollbackexception
.
under hood, spring creates 2 transactional interceptors: 1 mydao
, 1 myservice
. when daomethod()
marks transaction rollback, interceptor mydao
performs rollback , returns. stack moves interceptor myservice
, finds out previous rollback, , throws unexpectedrollbackexception
.
one solution remove @transactional
annotation mydao. not feasible right because mydao
used @ lot of places , cause errors.
another solution not set transaction rollback in daomethod()
rather mark servicemethod()
revert transaction on mycheckedexception
. don't solution because have lot of these "service methods" , have mark of them explicitly rollback on exception. add new service method in future have think of , therefore creates opportunities errors.
is there way keep setting transaction rollback daomethod()
, prevent spring throwing unexpectedrollbackexception
? instance, combination of parameters isolation
, propagation
?
throwing exception inside transaction trigger rollback, using setrollbackonly() redundant here , that's why have error.
if transactionnal on dao set propagation.required default, reuse existing transaction if there 1 or create 1 if there none. here should reuse transaction created @ service layer.
Comments
Post a Comment