420 likes | 437 Views
Java EE Transactions. Goals. Understand the basic concepts behind a transaction Be able to define transaction scope and properties within the EJB Tier. Objectives. Transaction Overview Transaction Scope Class Annotations and XML Descriptors SessionSynchronization Transaction Propagation
E N D
Java EE Transactions Java EETransactions
Java EE Transactions Goals • Understand the basic concepts behind a transaction • Be able to define transaction scope and properties within the EJB Tier
Java EE Transactions Objectives • Transaction Overview • Transaction Scope • Class Annotations and XML Descriptors • SessionSynchronization • Transaction Propagation • Isolation Issues • Database Locks • Isolation Levels • Programmatic and Optimistic Locking • Bean Managed Transactions • Exceptions and Transactions
Java EE Transactions Transactions • Unit of work that accesses one or more shared resources (usually databases) • set of one or more activities related to each other • must be completed together or not at all • cohesion of unit is normally mission critical • examples • ATM • withdraw from one source, deposit to another • Order System • locate item, charge account, schedule shipment • Medical System • identify medical state, dispense prescription
Java EE Transactions Transaction ACID Properties • Atomic • Transaction must execute completely or not at all • Consistent • Data in database is always in a consistent state (makes sense) • Constraints (primary keys, referential integrity, etc.) • Isolated • Transaction executes without interference • Durable • Changes are not lost if the system crashes
Java EE Transactions EJB Transaction Support • Declarative • transaction management controlled through deployment descriptor • Programmatic • direct programming calls • transaction management code mixed with business code • change in transactional behavior requires change in business code
Java EE Transactions Transaction Scope • javax.ejb.TransactionAttributeType • ** MANDATORY • tx must be active before calling • ** REQUIRED • tx will be created if not active • ** REQUIRES_NEW • new tx will created, no matter what • SUPPORTS • will join active transaction, but won't create one • NOT_SUPPORTED • won't join active transaction and won't create one • NEVER • tx must not be active when calling ** EJB3 strongly advises EntityManagers accessed within the scope of a JTA transaction; use one of these 3 for wrapping JPA implementations
Java EE Transactions Defining Transaction Attributes: Java Annotations • Defining global default for EJB @Stateless @TransactionAttribute(TransactionAttributeType.REQUIRED) public class HotelRegistrationEJB implements HotelRegistrationRemote, HotelRegistrationLocal { • Defining override for specific EJB method @Stateful @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) public class AgentReservationSessionEJB implements ... { ... @TransactionAttribute(TransactionAttributeType.REQUIRED) public Booking commit() throws AgentReservationException { ... } }
Java EE Transactions Defining Transaction Attributes: ejb-jar.xml • Defining a default for the EJB <enterprise-beans> <session> <ejb-name>HotelRegistrationEJB</ejb-name> ... </session> </enterprise-beans> <assembly-descriptor> <container-transaction> <method> <ejb-name>HotelRegistrationEJB</ejb-name> <method-name>*</method-name> </method> <trans-attribute>Required</trans-attribute> </container-transaction>
Java EE Transactions Defining Transaction Attributes: ejb-jar.xml • Defining a override for specific EJB method <container-transaction> <method> <ejb-name>HotelReservationSessionEJB</ejb-name> <method-name>*</method-name> </method> <trans-attribute>NotSupported</trans-attribute> </container-transaction> <container-transaction> <method> <ejb-name>HotelReservationSessionEJB</ejb-name> <method-name>commit</method-name> </method> <trans-attribute>Required</trans-attribute> </container-transaction>
Java EE Transactions Transaction Scope • Determines whether • transaction must exist • transaction is started • transaction is adopted • transaction is ignored • transaction can't exist
Java EE Transactions Not Supported • Transaction is suspended during the method of the Invoked EJB; resumes when method complete • Transaction scope is not propagated to Invoked EJB or anything it invokes Client Invoked EJB Thread of Execution No Transaction Context Client’s Transaction Context
Java EE Transactions Supports Client Invoked EJB • Joins the transaction context if invoked as part of a transaction (A) • Does not require a transaction; can be invoked outside of a transaction context (B) (A) (B) Thread of Execution No Transaction Context Client’s Transaction Context
Java EE Transactions Required Client Invoked EJB • Joins the transaction context if invoked as part of a transaction (A) • Initiates its own transaction context of invoked outside of a transaction (B) (A) (B) Thread of Execution No Transaction Context Client’s Transaction Context EJB’s Transaction Context
Java EE Transactions RequiresNew Client Invoked EJB • Initiates its own transaction context whether called within am existing transaction context (A) or outside of a transaction context (B) • Initiated transaction completes prior to returning to caller (A) (B) Thread of Execution No Transaction Context Client’s Transaction Context EJB’s Transaction Context
Java EE Transactions Mandatory Client Invoked EJB • Joins the transaction context if invoked as part of a transaction (A) • Throws a Transaction Exception if not called within a transaction context (B) (TransactionRequiredException for Remote Clients; TransactionRequiredLocalException for Local Clients) (A) (B) Transaction Exception Thread of Execution No Transaction Context Client’s Transaction Context
Java EE Transactions Never Client Invoked EJB • Throws a Transaction Exception if called within a transaction context (A) (RemoteException to Remote Clients; EJBException to Local Clients) • Must be invoked outside of a transaction context (B) (A) Transaction Exception (B) Thread of Execution No Transaction Context Client’s Transaction Context
Java EE Transactions Scenario: Transaction Scope • Client Creates 9 Valid and 1 Invalid Reservation HotelReservationSessionRemote session = //jndi.lookup for(int i=0; i<9; i++) { session.createReservation(person, startTime, endTime); } //now create a bad one session.createReservation(person, endTime, startTime); • Client requests to EJB to complete all Reservations try { session.commit(); } catch (InvalidParameterException ex) { ... } HotelRegistrationRemote reservationist = //jndi.lookup List mine = reservationist.getReservationsForPerson(person, 0, 100); if (mine.size() == 0) { log.info("all reservations were rolled back for: " + key); } else { log.info("" + mine.size() + " reservations were not rolled back for: " + key); }
Java EE Transactions Scenario: One Propogated Transaction • Calling EJB Starts Tx @Stateful @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) public class AgentReservationSessionEJB implements ... { @TransactionAttribute(TransactionAttributeType.REQUIRED) public Booking commit() throws AgentReservationException { /* for loop */ reservationist.createReservation( p.getPerson(), p.getStartDate(), p.getEndDate()); } • Called EJB Requires a Tx; willing to take existing @Stateless @TransactionAttribute(TransactionAttributeType.REQUIRED) public class HotelRegistrationEJB implements ... { public Reservation createReservation(...) throws HotelReservationException { if (startDate == null) { throw new InvalidParameterException(...); }
Java EE Transactions Sample Result • This one was specifically configured with REQUIRED -*** testBadCreates:RequiredSessionEJB *** -got expected exception:ejava.examples.txhotel.bl.InvalidParameterException: start date after end date -all reservations were rolled back for: RequiredSessionEJB • This one is one took the defaults -*** testBadCreates:HotelReservationSessionEJB *** -got expected exception:ejava.examples.txhotel.bl.InvalidParameterException: start date after end date -all reservations were rolled back for: HotelReservationSessionEJB
Java EE Transactions Scenario: New Transactions • Calling EJB Starts Tx @Stateful @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) public class AgentReservationSessionEJB implements ... { @TransactionAttribute(TransactionAttributeType.REQUIRED) public Booking commit() throws AgentReservationException { /* for loop */ reservationist.createReservation( p.getPerson(), p.getStartDate(), p.getEndDate()); } • Called EJB Requires a Tx; willing to take existing @Stateless @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) public class HotelRegistrationEJB implements ... { public Reservation createReservation(...) throws HotelReservationException { if (startDate == null) { throw new InvalidParameterException(...); }
Java EE Transactions Scenario: One Propogated Transaction • Configured with REQUIRES_NEW -*** testBadCreates:RequiresNewSessionEJB *** -got expected exception:ejava.examples.txhotel.bl.InvalidParameterException: start date after end date -9 reservations were not rolled back for: RequiresNewSessionEJB
Java EE Transactions Transaction Propogation
Java EE Transactions Persistence ContextTransaction Propogation • Tx-scoped Entity Manager called outside of Tx • creates transaction on entry • creates a new tx-scoped persistence context • commits transaction and detaches entities on exit • Tx-scoped Entity Manager called with active Tx • creates new tx-scoped persistence context if needed • uses existing persistence context if present • i.e., persistence context passed from EJB to EJB within Tx • Exception thrown if persistence context passed to Stateful Session Bean using extended entity manager • Extended persistence context from Stateful Session Bean is passed to tx-scoped Entity Managers when Stateless Session Bean called • Stateful Session Beans may only share extended persistence contexts with Stateful Session Beans injected by the container • Persistence Contexts do not cross Tx scope boundaries
Java EE Transactions SessionSynchronization • Stateful Session Bean • contain client state • similar in concept to HttpSession • state may be tx-sensitive • may receive transaction lifecycle events • unlike HttpSession
Java EE Transactions SessionSynchronization @Stateful public class HotelReservationSessionEJB implements HotelReservationSessionLocal, HotelReservationSessionRemote, javax.ejb.SessionSynchronization { public void afterBegin() { log.debug("*** Transaction Started ***"); } public void beforeCompletion() throws EJBException, RemoteException { log.debug("*** Transaction about to complete ***"); } public void afterCompletion(boolean status) { log.debug("*** Transaction Completed:" + status + " ***"); }
Java EE Transactions SessionSynchronization [HotelReservationSessionEJB] *** HotelReservationSessionEJB *** [HotelReservationSessionEJB] ctx=org.jboss.ejb3.BaseSessionContext@ef27e3 [HotelReservationSessionEJB] reservationist=RequiresNewEJB [HotelReservationSessionEJB] *** Transaction Started *** [HotelReservationSessionImpl] ************ creating 10 reservations *** [HotelReservationSessionEJB] *** Transaction about to complete *** [HotelReservationSessionEJB] *** Transaction Completed:true *** [HotelReservationSessionEJB] *** HotelReservationSessionEJB closing *** [HotelReservationSessionEJB] *** HotelReservationSessionEJB *** [HotelReservationSessionEJB] ctx=org.jboss.ejb3.BaseSessionContext@11de6a0 [HotelReservationSessionEJB] reservationist=HotelRegistrationEJB [HotelReservationSessionEJB] *** Transaction Started *** [HotelReservationSessionImpl] ************ creating 10 reservations *** [HotelRegistrationEJB] error creating reservation, rolling back transaction:start date after end date [HotelReservationSessionEJB] *** Transaction Completed:false *** [HotelReservationSessionEJB] *** HotelReservationSessionEJB closing ***
Java EE Transactions Transaction Isolation • What happens when two or more transactions attempt to access the same data • Dirty Reads • first transaction reads uncommitted changes from a second transaction that may eventually be rolled back • Repeatable Reads • data guaranteed to be the same if read multiple times during the same transaction; implemented with locks or snapshots • Phantom Reads • first transaction sees new rows added by second transaction
Java EE Transactions Database Locks • How do you prevent overlapping transactions from viewing the other’s data • Read Lock • data is prevented from changing while transaction in progress • Write Lock • prevents other transactions from modifying the data • permits dirty reads by other transactions • Exclusive Write Lock • prevents other transactions from reading and modifying data • prevents dirty reads
Java EE Transactions Transaction Isolation Levels • Read Uncommitted • can read data being modified by another transaction • allows dirty, non-repeatable, and phantom reads • Read Committed • cannot read data being modified by another transaction • allows non-repeatable and phantom reads; prevents dirty reads • Repeatable Read • cannot change data being read by another transaction • allows phantom reads; prevents dirty and non-repeatable reads • Serializable • transactions can neither read or write same data
Java EE Transactions Locking • Programmatic Locking • EntityManager.lock(object, LockModeType) • LockModeType.READ • LockModeType.WRITE • Constrains system to work sequentially on locked resources • Bottleneck • Vendors not required to support unless @Version field supplied • Optimistic Locking • Permits parallel processing of information • Assumes that conflicts rarely occur • Error correction occurs after conflict detected
Java EE Transactions Optimistic Locking Problem • Client requests a Reservation Reservation reservation = new Reservation(...); em.persist(em); return reservation; • A second client request obtains another copy return em.find(Reservation.class, id); • The first client makes a change reservation.setStartDate(...) • The second client makes a change reservation.setCost(...) • The first client change is made on server em.merge(reservation) • The second client change is made on server em.merge(reservation) • Impact, the first client change is lost
Java EE Transactions javax.persistence Support • Add a version field to the class and annotate public class Reservation implements Serializable { @Id private long id; @Version private long version; private String confirmation; private Date startDate; private Date endDate; private Person person; • Or provide metadata about existing field <entity class="ejava.examples.txhotel.bo.Reservation" <attributes> <id name="id"/> <version name="version"/> </attributes> </entity>
Java EE Transactions javax.persistence Support • EntityManager will check whether update is using current version of class or will throw exception reservation.setVersion(version - 1); start.add(Calendar.DAY_OF_YEAR, 1); reservation.setStartDate(start.getTime()); log.debug("trying to change:" + reservation); try { reservation = em.merge(reservation); fail("failed to check version"); } catch (OptimisticLockException ex) { log.debug("caught expected exception:" + ex); }
Java EE Transactions Manual Transaction Control • Java Transaction Service (JTS) • Java implementation of the OMG Object Transaction Service (OTS) • robust, complete, and complicated • Java Transaction API (JTA) • simplified • javax.transaction • Java EE registers manual JTA interface in JNDI • java:comp/UserTransaction • also available from SessionContext.getUserTransaction(); • example • UserTransaction tx = //... • tx.begin(); • do something • tx.commit(); //or rollback • can be used by Session Beans • @Stateless • @TransactionManagement(TransactionManagerType.BEAN) • public class ...
Java EE Transactions Bean Managed Transactions • Stateless Session Beans • transactions must begin and end within the scope of a single method • Stateful Session Beans • transaction may begin and end in separate methods
Java EE Transactions Exceptions and Transactions • Default • Checked Exceptions do not impact transactions • System Exceptions automatically rollback transaction • sub-classes of RuntimeException • EJBException • NullPointerException • RemoteException • Customization • Checked exceptions can be configured to rollback transaction <assembly-descriptor> <application-exception> <exception-class>java.sql.SQLException</exception> <rollback>true</rollback> <application-exception> <assembly-descriptor>
Java EE Transactions Summary • ACID Transactions • Automic, Consistent, Isolated, Durable • Transaction Scope • Mandatory, Required, RequiresNew, Supports, NotSupported, Never • Class Annotations and XML Descriptors • Is the Java code that independent of the transaction configuration? • Are there portability issues from environment to environment • SessionSynchronization
Java EE Transactions Summary (cont.) • Isolation Issues • dirty reads • repeatable reads • phantom reads • Database Locks • Read Locks • Write Locks • Exclusive Write Locks • Isolation Levels • Read Uncommitted • Read Committed • Repeatable Read • Serializable
Java EE Transactions Summary (cont.) • Locking • Programmatic • Optimistic • Bean Managed Transactions • JTA UserTransaction • Exceptions and Transactions
Java EE Transactions References • “Enterprise JavaBeans 3.0, 5th Edition”; Burke & Monsen-Haefel; ISBN 0-596-00978-X; O'Reilly