Let's say that we have a non-EJB application, although I think we would have the same questions for an EJB application using BMT beans, with something like this.
The business logic layer has a Facade and beans.
The storage layer has a DAO and other classes for the persistant data store access.
Now, if we have coarse-grained methods, we would do something like this. In the DAO method, we:
Start a transaction Do processing commit or rollback End transaction
But suppose we have multiple DAOs or multiple databases or fine-grained methods. Then I think we would need to do something like this. The Facade would be the starting point, eg:
Facade starts transaction Facade invokes bean method(s) which invoke DAO method(s) Facade commits or rolls back Face ends transaction
I was initially uneasy about the Facade doing all of this, principally because you have an object in the Business Logic layer which knows about the persistant layer, eg there is a relational database being used as a persistant store. But I can't see any way round it, and Sun's design pattern website does say that it makes sense to use the Facade to centralise Transaction Management (see http://java.sun.com/blueprints/corej2eepatterns/Patterns/SessionFacade.html).
So, if you start a transaction from a Facade, it looks as if it make sense to also commit or rollback from a Facade.
You're not EJB but the CMT model might be instructive. There the transaction span equals the top-most public method called from the client with automatic start and commit. The only thing the code can do to alter the flow is to mark the transaction ROLLBACK-ONLY after which it cannot be committed, or allow an exception to escape the public method. As I recall this is consistent with my mainframe CICS days where by default the system issued a commit at the end of the top level call from the client. I'd guess most TPMs have an option like this, too.
All this is based on the idea that the client expects the entire request to be ACID with no knowlege of how many facades, DAOs, tables, databases, messages and other stuff might be involved. If you change that client expectation you might have to change the rules.
We do some BMT where we must have sub-transactions. If one of those fails and rolls back we try something else, but still want the overall client request to commit and count as a success.
A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
posted 15 years ago
The strategy I described works with flat transactions as well as nested transactions.
Transaction control, in my mind, is one of the fundamental concepts which developers should learn, preferably in school. However, it doesn't seem to get the coverage it deserves. Sigh.
If you are an EJB developer, you'd need to understand transactions. But it's certainly true that knowledge about transaction management is neither deep not widespread. Part of the reason is the poor quality of the tutorials around. I mean, the question I posed at the start of this thread should not have been necessary if I had obtained the answer from the usual sources.
On another point, I realised after I made my post that you can't use a facade to manage transactions for BMT beans as these beans cannot run in an incoming transaction. And I must admit that, for session beans, I've simply used CMT. However, for non-EJB applications like the one which I'm working on now, I've had to think harder about transaction management but found a dearth of useful material on this subject. I'm pretty convinced that you should have some class which handles transaction management as it looks plain wrong for a business object to do this sort of thing. I think that the facade is the right class for transaction management, and it would be good to hear other peoples' views on this.