class ExtHotelApiService extends HotelApiService {
static scope = "singleton"
static transactional = true
def save(params) {
params.hotels.each{ht->
try{
transactionalSave(ht)
} catch(Exception e) {
/* exceptions handling */
}
}
}
@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW, rollBackFor=RollBackError.class)
def transactionalSave(ht) thro开发者_运维技巧ws RollBackError {
/* saving hotel and hotel description */
}
}
Note few things:
- ExtHotelApiService extends HotelApiService
- RollBackError extends RuntimeException
- ExtHotelApiService.transactional = true
- HotelApiService.transactional = false
- We must save hotel and only then save the description
- We must roll back transaction (and not persist hotel) if description is not valid (can't be persisted)
All code was wrote according to Declarative Transactions guide but there is one trouble - no roll back happens at all! :(
Transaction successfully commits and hotel is persisted into DB even after RollBackError is thrown!
Where i have make mistake and how to work with declarative transactions in right way ?
The default behaviour for Spring's declarative transaction management tells the transaction manager to rollback for any unchecked exception, and to ignore any checked exceptions. Checked exceptions can be declared to trigger a rollback, but if the default @Transactional settings are left intact, a checked exception won't have any impact on the current transaction.
The Spring documentation on this is available here, and the relevant sections are 10.5.5, and 10.5.6. Specifically note the following:
Any RuntimeException triggers rollback, and any checked Exception does not.
精彩评论