package study.ejb2.transaction.cmt.stateful;

import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.ejb.SessionSynchronization;

/**
 * When using CMT we need declared the attributes which will role
 * the behavior.
 * 
 * The transaction attribute can be:
 * > Required
 *   If the method is called with an existing transaction context, the method
 *   runs in that transaction. Otherwise the Container will start a new one.
 * > RequiresNew
 *   The method will always run with a new transaction. If the method is called
 *   with an existing transaction context, the caller's transaction is suspended
 *   until this method completes.
 * > Mandatory
 *   The method requires an existing transaction. If the method is called without
 *   an existing transaction context, the Container will throw an exception.
 * > Supports
 *   Doesn't metter if the caller has or not a transaction context. If it has the
 *   method runs in the same transaction, otherwise runs with an "unspecified
 *   transaction context".
 * > NotSupported
 *   Always runs with an "unspecified transaction context". If the caller has a
 *   transaction, it will be suspended. 
 * > Never
 *   The method requires an "unspecified transaction context". If the method is
 *   called with an existing transaction context, the Container will throw an
 *   exception.
 * 
 * The Container will rollback only if we tell to do it (calling setRollbackOnly)
 * or if we throw a system exception (unchecked - runtime), like EJBException.
 * 
 * The interface SessionSynchronization allows the bean to have 3 new lifecycle
 * methods, those methods will be called when a transaction starts, ends and
 * commit/rollback.
 */
public class EjbStatefulDiceBean implements SessionBean, SessionSynchronization {
	private static final long serialVersionUID = -625509719560931198L;
	private SessionContext ctx;

	public void setSessionContext(SessionContext ctx) {
		System.out.println("setSessionContext");
		this.ctx = ctx;
	}
	
	public void ejbCreate() {
		System.out.println("ejbCreate");
	}
	
	public void ejbActivate() {
		System.out.println("ejbActive");
	}

	public void ejbPassivate() {
		System.out.println("ejbPassivate");
	}

	public void ejbRemove() {
		System.out.println("ejbRemove");
	}

	/**
	 * This method runs in a transactional state. If this beans will be deployed
	 * as a Stateless Bean so it MUST start and finish the transaction in the same
	 * method (only Entity Bean can start in one method and finish in another). 
	 */
	public int rollDiceInAcid() {
		// tells to Container rolls back
		ctx.setRollbackOnly();
		
		return (int) (Math.random() * 6) + 1;
	}

	/* 
	 * The following method are from SessionSynchronization, they extend the capability
	 * of the bean to know when the transaction start, end and commit or rollback.
	 * We can use only with Stateful Session Bean, because Stateful has state of a specific
	 * client, so we can persiste or load data from database before or after the business
	 * method (like ejbStore and ejbLoad of an Entity bean).
	 */
	/**
	 * This method is called just after the transaction has started and before the business
	 * method run.
	 * Here we can do anything, we have a "meaningful transaction context".
	 * @see javax.ejb.SessionSynchronization#afterBegin()
	 */
	public void afterBegin() {
		System.out.println("The transaction has started");
	}

	/**
	 * This method is called just before the transaction ends and after the business
	 * method completes.
	 * Here we can do anything, we still have a "meaningful transaction context".
	 * @see javax.ejb.SessionSynchronization#beforeCompletion()
	 */
	public void beforeCompletion() {
		
	}
	
	/**
	 * This method is called after the transaction has ended either in a commit or rollback.
	 * The given boolean indicates if the transaction was commited (when is true) or was
	 * rolled back.
	 * @see javax.ejb.SessionSynchronization#afterCompletion(boolean)
	 */
	public void afterCompletion(boolean committed) {
		System.out.println("About to end the transaction");
	}
}

@@ -3786,16 +3786,67 @@
 () %7B%0D%0A%09%09
+System.out.println(%22About to end the transaction%22);
 %0D%0A%09%7D%0D%0A%09%0D
@@ -4199,37 +4199,36 @@
 ln(%22
-About to end the transaction%22
+Was committed? %22 + committed
 );%0D%0A

Update EjbStatefulDiceBean.java