4 Replies Latest reply: Jan 21, 2014 8:29 AM by Peter René Menges RSS

EJB transactions

user10397781 Newbie
Currently Being Moderated

I am developing a Web Service using a Stateless EJB, which has a single entry point (method). This method has 3 steps and I want step 1 to occur in a different transaction than steps 2 and 3 (which should be in the same transaction). These "steps" consist in callings to injected Stateless EJBs. Let me explain with some code:

 

@Stateless
@WebService(...)
public class MyWebServiceImpl implements MyWebService {
     @EJB
     private UserBusinessBean userBusinessBean;
     @EJB
     private EventsBusinessBean eventsBusinessBean;
     @WebMethod(...)
     public MyWebServiceResult process(MyWebServiceParam param) {
          // extract data from param
          EventResult createEventResult = eventsBusinessBean.createEvent(data); // step 1
          // do some extra processing
          User user = userBusinessBean.createUser(someData); // step 2
          // do some extra processing
          EventResult updateEventResult = eventsBusinessBean.updateEvent(moreData); // step 3
     }
}

 

The 2 injected EJBs are themselves Stateless and have injected references to Stateless DAOs, whose function is to call stored procedures on the database.

I need to have step 1 executing in one transaction and steps 2 and 3 executing in another transaction (because if step 2 or 3 fails, the info from step 1 is already committed).

I know I have 2 options to implement this: container-manager transactions or user-managed transactions. I believe the former approach is more safe than the latter, delegating the management to the container (in my case, a Weblogic server). But I can't understand how I should use the EJB Transactions Annotations to implement this logic. Should I annotate the methods from my injected Business Beans? And what about the DAOs, do they need to have annotations too? And which ones should I use?

 

I hope you can give me some help in this one. Let me know if you need to know more details from my implementation.

  • 1. Re: EJB transactions
    gimbal2 Guru
    Currently Being Moderated

    Basically, you need to apply the proper transaction attributes but only at the entry point of a chain of calls where it is required. If you use 'CREATE_NEW' for example, then the EJB invocation will create a nested transaction of its own in stead of adopting the transaction that already existed. Any work done in that "inner" transaction will be committed and will not affect the "outer" transaction, which is suspended until the "inner" EJB invocation finishes.

     

    Any tutorial on EJB tech will explain which transaction attributes exist and what they globally do. Properly applying them in stead of always just using the default (REQUIRED) can help you to create a more controlled transactional environment in which you have the chance of catching transactional mistakes early on (for example: if you have code for which you know a transaction MUST exist for it to succeed, than the attribute 'MANDATORY' is helpful). You'll find that this little bit of micro management is what will make EJB tech a bit harder to apply at first, but in the end when you start to "see the matrix" it will actually start to help you lay down a clean code design. That takes experience though.

  • 2. Re: EJB transactions
    user10397781 Newbie
    Currently Being Moderated

    gimbal2 wrote:

     

    Basically, you need to apply the proper transaction attributes but only at the entry point of a chain of calls where it is required. If you use 'CREATE_NEW' for example, then the EJB invocation will create a nested transaction of its own in stead of adopting the transaction that already existed. Any work done in that "inner" transaction will be committed and will not affect the "outer" transaction, which is suspended until the "inner" EJB invocation finishes.

    Thanks for the tip. I wasn't remembering that my Web Service implementation class, being a Stateless EJB, had an implicit REQUIRED attribute in the "process" method, and that was confusing me because I didn't know if there was already a transaction going on. I ended up adding the REQUIRES_NEW attribute in the method "createEvent" from my EventsBusinessBean and created some ApplicationExceptions to rollback the transactions.

  • 3. Re: EJB transactions
    gimbal2 Guru
    Currently Being Moderated

    Sounds like a job well done!

  • 4. Re: EJB transactions
    Peter René Menges Newbie
    Currently Being Moderated

    Hm ... not too sure about that. The transaction attributes in the described workflow depend on the invocation order of the business methods of the other beans.

    EventResult createEventResult = eventsBusinessBean.createEvent(data); // step 1 


    User user = userBusinessBean.createUser(someData); // step 2
    EventResult updateEventResult = eventsBusinessBean.updateEvent(moreData); // step 3 


    1 + 2 should be both in the same transaction per requirement.

    So which of the methods is used to start this transaction? Consider someone doing something like:

     

    EventResult createEventResult = eventsBusinessBean.createEvent(data); // step 1 


    EventResult updateEventResult = eventsBusinessBean.updateEvent(moreData); // step 3
    User user = userBusinessBean.createUser(someData); // step 2

     

    <i>If the invocation of userBusinessBean.createUser starts a new transaction, in the first case both userBusinessBean.createUser and eventsBusinessBean.updateEvent are within the same transaction but in the second case eventsBusinessBean.updateEvent is executed within the transaction of userBusinessBean.createUser</i>.

     



Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points