I'm experimenting with using the command pattern to allow my web layer to work with Hibernate entities within the context of a single transaction (thus avoiding lazy loading exceptions). I am, however, confused now with how I should deal with transactions.
My commands call service layer methods that are annotated with @Transactional
annotations. Some of these service layer methods are read-only - e.g. @Transactional(readOnly = true)
- and some are read/write.
My service layer exposes a command handler that executes commands passed to it on behalf of the web layer.
@Transactional
public Command handle(Command cmd) throws CommandException
I assume I am right in making the command handler's handle
method transactional. This is where the confusion comes in. If the implementation of a command makes calls to multiple service layer methods, there is no way for the command handler to know whether operations called within the command will be read-only, read/write or a combination of the two.
I don't understand how propagation works in this example. If I were to make the handle()
method readOnly = true
, then what happens if the command then calls a service layer method that is annotated with @Transactional(realOnly = false)
?
handle()
may call methods which write, the transaction must allow writes. That would be fine & correct as a solution. If you really wanted, you could investigate starting the TX programmatically & switching readOnly -- perhaps via an attribute of Command -- but I seriously doubt it's worth the effort. – Coiffeur