package study.ejb3.transaction.cmt.stateless; import javax.annotation.Resource; import javax.ejb.SessionContext; import javax.ejb.Stateless; import javax.ejb.TransactionAttribute; import javax.ejb.TransactionAttributeType; /** * When managing transactions declaratively, you delegate the demarcation policy to * the Container. * By default all methods has the transaction attribute Required. * With EJB 3.x we can set the transaction attribute through @TransactionAttribute * annotation too. * The transaction won't be propagated with asynchronous method invocation. * * The transaction attribute defined in the ejb-jar.xml will override the annotation. * * In EJB 3.1, we can make a application exception (checked exception) force the container * roll back the transaction. To do that we need annotate the declared class which extends * Exception (or its checked subclasses) with @ApplicationException(rollback=true). Thus, * when we throw that exception the Container will roll back the transaction. If we annotate * a system exception (unchecked exception) with @ApplicationException(rollback=false) the * Container won't rolls back. */ @Stateless //@TransactionManagement(TransactionManagementType.CONTAINER) default //all methods will use this transaction attribute @TransactionAttribute(TransactionAttributeType.REQUIRED) public class EjbStatelessDiceBean { @Resource private SessionContext ctx; /** * This method uses the transaction attribute defined in * the level-class. */ public int rollDDDice() { int dice = (int) (Math.random() * 12) + 1; // do some move if(dice == 7) { // you lost ctx.setRollbackOnly(); // rolls back the transaction } return dice; } /** * This method uses this transaction attribute defined (REQUIRES_NEW). */ @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) public int rollDiceInAcid() { return (int) (Math.random() * 6) + 1; } public void aDangerousMethod() throws MyApplicationException { // do dangerous things throw new MyApplicationException(); // the Container will rolls back } }