EJB is by default handling transaction management, and as I read, hibernate also handle transaction. When I talk about a transaction, I have the understanding of rollback a database persist operation like functionality.
My question is how a application which use both EJB and Hibernate we selectively choose one transaction provider to support? Also can both EJB and hibernate transaction work simultaneously?
Hibernate and EJB transactions can and do work together simultaneously. By default, when an EJB call is made, the call will be in an EJB transaction which can be committed or rolled back. If you happen to make a hibernate call within that EJB call (or in a MDB), and that transaction is rolled back, the hibernate database transaction will also roll back. In this scenario, when you do a transaction commit, hibernate will also commit the database transaction.
The way I think of it is this: an EJB transaction wraps around a Hibernate database transaction, and the database transaction depends on the EJB transaction to be committed. If the EJB transaction fails, so does the database transaction. If the EJB transaction commits, so does the database transaction.
Example #1 - successful transaction:
EJB method
|--> Transaction Started
|
|--> Call persist method on Entity Manager instance
|
|--> SQL insert statement added to database transaction
...
|--> EJB Transaction committed
| --> SQL insert statement committed to database
Example #2 - rolled-back transaction:
EJB method
|--> Transaction Started
|
|--> Call persist method on Entity Manager instance
|
|--> SQL insert statement added to database transaction
...
X--> EJB Transaction rolls back
X --> Database transaction rolls back (insert not performed)
Furthermore, if you are nesting EJB calls (for instance, one EJB method calls another), by default, they all live in the same transaction. So the entire hierarchy of calls must complete successfully in order for all of the EJB and Hibernate calls to commit.
Example #3 - nested EJB transactions:
EJB method
|--> Transaction Started
|
|--> Call persist method on Entity Manager instance
|--> SQL insert statement added to database transaction
...
|--> Another EJB method called, *continues* same transaction
|
|--> EJB method successfully commits
...
|--> EJB Transaction committed
| --> SQL insert statement committed to database
Example #4 - nested EJB transaction with rollback:
EJB method
|--> Transaction Started
|
|--> Call persist method on Entity Manager instance
|
|--> SQL insert statement added to database transaction
...
|--> Another EJB method called, *continues* same transaction
|
X--> EJB method rolls back
...
X--> EJB Transaction rolls back
X --> Database transaction rolled back (insert not performed)
You can change this behavior by managing the transactions yourself, OR by demarcating your methods with @TransactionAttribute
s if you are using Container Managed Transactions (i.e. letting the container do the hard work).
This Guide has a lot of good information about transactions and hibernate.