EJB with transactional state
Problem: EJBean, like any POJO, can have fields. We want the changes made to the fields to be rolled back if a transaction is rolled back.
Let us consider the following scenario:
- Client starts transaction
- Client invokes EJB and propagates transaction
- Assume that EJBean have field int number initially equals 0, method invoked by client sets the field number to 1
- Client rollbacks transaction
- It turns out that value of field number is not rolled back, the value remains 1
EJB supports global transactions but they are not transactional. I.e. they can propagate transaction to Managed Resources, for instance a database connection, but the state of EJBean does not participate in a transaction, like in the above scenario.
To make a state of EJB transactional, we must do it manually, i.e. we must provide a mechanism that restores state in a case of rollback. This can be achieved by transaction listeners. But only possible type of EJB that support such listeners is Stateful Session Bean.
@Stateful public class TUBean { private TUState state; private TUState rollbackState; @PostConstruct private void init(){ state = new TUState(); } //business methods @AfterBegin private void afterBegin(){ rollbackState = state.clone(); } @AfterCompletion private void afterCompletion(boolean committed){ if ( ! committed ) state = rollbackState; rollbackState = null; } }
The class TUState encapsulates whole transactional state. The state is rather simple, like POJO, without database connections. For convenience we assume that the method clone is well implemented.