Hi, I m confused about the use of some of the rollback methods in the UserTransaction interface when using BMT. When should we use UserTransaction's setRollbackOnly() and when should we use UserTransaction's rollback()? Cant we always use UserTransaction's rollback() to rollback a transaction? Please advise. Thanks.
Howdy So, you have two choices: BMT and CMT. (unless you're an entity, in which case you're CMT) With BMT, your job is to demarcate the start and end of the transaction. You use your context (EJBContext) to get yourself a UserTransaction, and off you go... UserTransaction ut = ctx.getUserTransaction(); Then you start it... ut.begin(); Then you end it in either a commit or a rollback: ut.commit(); OR ut.rollback(); But there are TWO different setRollbackOnly() methods, and ONE getRollbackOnly() method. Both UserTransaction and EJBContext have a setRollbackOnly(). So, if you are BMT, just remember that the ONLY transaction-related thing that you do with your EJBContext is simply to GET the UserTransaction. That's it. After that, EVERYTHING a BMT bean does with respect to transactions is in UserTransaction interface. So that means: BMT == UserTransaction.setRollbackOnly() And why would you use it? Because you might know the transaction is going badly *before* you reach the place where the transaction actually ends. You might not want to end the tx at the moment you discover it won't work, for many reasons. Perhaps you want to keep only one place in your code where the transaction ends. Or... you might need the rest of the transactional code to run for other side-effects, who knows. (I have a hard time coming up with good reasons) CMT == EJBContext.setRollbackOnly() Why use THAT? Because a CMT bean has no API for controlling the transaction, so calling setRollbackOnly() is the CMT bean's way of saying to the container "Do NOT commit this transaction!" Then we come to getRollbackOnly(). That method lives in only ONE interface, EJBContext. Why use it? If a bean is doing some transactional work, the bean might want to find out if that work is pointless, since the transaction has already been given a death sentence. So a CMT bean calls EJBContext.setRollbackOnly() to make sure that some other transaction participant has not previously called setRollbackOnly. (keep in mind that a CMT bean might be participating in a tx started by a BMT bean; but who/what started the tx is transparent to the CMT bean) (and keep in mind that a BMT bean can participate ONLY in transactions that the BMT bean himself started. No transaction will propogate in to a method call on a BMT bean.) So if there's no getRollbackOnly() in UserTransaction, how does a BMT bean find out if someone called setRollbackOnly() on the tx? By calling getStatus() on the UserTransaction interface (which gives you a status code -- there are bunch -- you do NOT need to know what these are on the exam.) Summary of what is legal: BMT: EJBContext.getUserTransaction() UserTransaction.begin UserTransaction.commit UserTransaction.rollback UserTransaction.setRollbackOnly() UserTransaction.getStatus() CMT: EJBContext.setRollbackOnly() EJBContext.getRollbackOnly() That's it!! A CMT cannot call ANYTHING in UserTransaction. In fact, a CMT isn't even allowed to *think* about UserTransactions. (and the container can tell...) A BMT bean cannot call ANYTHING that is transaction-related in EJBContext, *except* getUserTransaction. After that, it is UserTransaction all the way down for a BMT bean. Whew! cheers, Kathy
Co-Author of <a href="http://www.amazon.com/exec/obidos/ASIN/0596007124/ref=jranch-20" target="_blank" rel="nofollow">"Head First Design Patterns"</a><br /> <br />Just a Jini girl living in a J2EE world.