|
In a Bean Managed Transaction, the code in the session or message-driven bean explicitly marks the boundaries of the transaction. Although beans with container-managed transactions require less coding, they have one limitation: When a method is executing, it can be associated with either a single transaction or no transaction at all. If this limitation will make coding your bean difficult, you should consider using bean-managed transactions. How do you code an EJB 3 using bean managed transactions ?
That's quite easy : no ejb-jar.xml needed to describe the Transaction policy!
Recall our previous EJB 3.0 Stateless SB. Let's add some annotations !
|
package com.sample;
import java.io.Serializable;
import java.util.List;
import javax.annotation.Resource;
import javax.ejb.*;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;
@Stateless
@javax.ejb.ApplicationException(rollback = true)
@TransactionManagement(TransactionManagementType.BEAN)
@Remote
public class HelloBean implements HelloBeanItf, Serializable {
@Resource
private UserTransaction utx;
@PersistenceContext(unitName="userDatabase")
private EntityManager em;
public List<Note> findAll() {
Query query = em.createQuery("Select h from Note h");
return (List<Note>) query.getResultList();
}
/** Insert a new gadget into the catalog */
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void newNote(Note note1,Note note2) {
try {
int dummy = 0;
utx.begin();
em.persist(note1);
if (dummy == 0)
throw new EJBException("Simulating an Error");
em.persist(note2);
utx.commit();
}
catch (Exception e) {
try {
utx.rollback();
} catch (IllegalStateException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (SecurityException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (SystemException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
}
}
}
|
Basically the Transaction Management strategy is declared with this annotation:
@TransactionManagement(TransactionManagementType.BEAN)
The next one should sound you familiar, it's the Attribute type we have learnt about since EJB 1.0
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
one important annotation is this:
@javax.ejb.ApplicationException(rollback = true)
Specifies whether the EJB container should rollback the transaction, if the bean is currently being invoked inside of one, if the exception is thrown.
Valid values for this attribute are true and false. Default value is false, or the transaction should not be rolled back.
Need a refresh on what is an application exception ?
An application exception signals an error in the business logic of an enterprise bean.
It differs from a system exception indicates a problem with the services that support an application.
As last annotation we have injected the UserTransaction Object as a Resource in our EJB
@Resource
private UserTransaction utx;
Nothing new.
So what happens here ? we insert a Note Object, we persist it, then an exception is thrown.
As you can see if you successfully deployed the Bean, the Transaction is rolled back and
no data is inserted.
That's all. I've told you it was easy !
|