Reputation: 18347
I have a service class that calls other utility classes. These classes themselves sometimes
save domain objects and flush them (ex: new User(...).save(flush:true)
). I'm calling my service class from a test.
Is my service transactional?
From what I can see in the logs, the Flush Mode is always changing:
impl.SessionImpl setting flush mode to: MANUAL
hibernate.SQL select this_.id as i...
type.StringType binding '1rAdPVixha' to parameter
....
impl.SessionImpl setting flush mode to: AUTO
But my real questions is: If my service method is transactional when called outside of the service (eg: in a test), how can I force the service to rollback all data?
EDIT: I found this:
TransactionAspectSupport.currentTransactionInfo().transactionStatus.setRollbackOnly()
But I still want to know if my service is fully transactional, ie, even if I call domain.save(flush:true) from an utility class within my service method it will run in the same tx context.
Like this:
void testSomething() {
svc.process(data);
assert data.exists() ;// true if no rollback happened
}
class MySvc() {
void process(data) {
myUtil.process(data);
}
}
class MyUtil {
void process(data) { data.save(flush:true)}
}
Upvotes: 2
Views: 1651
Reputation: 75681
The transaction is bound to the thread, and assuming each transactional method has the default 'required' propagation setting, secondary calls will join the active transaction. The initiating call will commit when it finishes, unless something triggers a rollback (a runtime exception or explicit call).
Keep in mind that flush is different from commit. A transactional method will set autocommit to false on the connection, so flushing will push data to the database but it'll be kept in the a temporary transaction queue in case rollback is required. You can flush multiple times, for example if you're doing many inserts and want to reduce application memory usage. When you commit the database will make the temporary changes permanent.
Upvotes: 3