Enterprise Java Development@TOPIC@

Chapter 101. Persistence Context Propagation

101.1. Stateless Persistence Context Interaction
101.1.1. Stateless EJB Example Check-in
101.1.2. Stateless EJB Example Client Check-in
101.1.3. EJB Gets Available Rooms from DB
101.1.4. EJB Gets Specific Room
101.1.5. EJB Adds Guest
101.1.6. EJB associates Guest with Room
101.2. Stateful Facade Persistence Context Interaction
101.2.1. Example Stateful Reservation EJB Caches Guest Requests for Client
101.2.2. Example Stateful Reservation EJB Acting on Cached State
101.2.3. Stateful EJB Example Client Check-in
101.2.4. Stateful EJB Persists Guests Prior to Active JTA Transaction
101.2.5. Stateless EJB Populates Propagated Persistence Context with Rooms
101.2.6. Stateful EJB Method Activates Transaction and flush()es Guests in EntityManager Cache
101.2.7. Stateful EJB uses pre-loaded Rooms and Guests without accessing DB (until association)
101.3. Transaction Rollbacks
101.3.1. Stateless Transaction Rollback
101.3.2. Stateful Transaction Rollback
101.4. Pessamistic Locking
101.5. Summary

Figure 101.1. Persistence and Transaction Context Propagation

Persistence and Transaction Context Propagation

  • EJB will instantiate persistence context if does not yet exist

  • Stateless EJBs may only have transaction-scope persistence contexts

  • Stateful EJBs may have transaction-scope or extended persistence contexts

  • EJBs can share persistence contexts

    • Stateless EJB can propagate its tx-scope persistence context to a called EJB

    • Stateful EJB can propagate its tx-scoped or extended persistence context to a called EJB

    • Stateless EJB can work with extended persistence context provided by upstream Stateful client

    • Stateful EJB cannot transform propagated tx-scope persistence context into an extended

  • EJB Facade can act as sharing point for common persistence context

guest = hotelMgmt.checkIn(guest, room); //<== will attempt to also persist guest



[HotelMgmtEJB] *** HotelMgmtEJB(1086999670):init ***
[HotelMgmtEJB] checkin(guest=Guest [id=65, name=member 0], room=Room [number=1, occupant=null])
[HotelMgmtEJB] *** HotelMgmtEJB(1086999670):destroy ***
[HotelMgmtEJB] *** HotelMgmtEJB(99312186):init ***
[HotelMgmtEJB] checkin(guest=Guest [id=66, name=member 1], room=Room [number=100, occupant=null])
[HotelMgmtEJB] *** HotelMgmtEJB(99312186):destroy ***
[HotelMgmtEJB] *** HotelMgmtEJB(545116383):init ***
[HotelMgmtEJB] checkin(guest=Guest [id=67, name=member 2], room=Room [number=102, occupant=null])
[HotelMgmtEJB] *** HotelMgmtEJB(545116383):destroy ***
[HotelMgmtEJB] *** HotelMgmtEJB(605810979):init ***
[HotelMgmtEJB] checkin(guest=Guest [id=68, name=member 3], room=Room [number=201, occupant=null])
[HotelMgmtEJB] *** HotelMgmtEJB(605810979):destroy ***
[stdout] Hibernate: 
[stdout]     update
[stdout]         EJBJPA_ROOM 
[stdout]     set
[stdout]         FLOOR_ID=?,
[stdout]         OCCUPANT_ID=? 
[stdout]     where
[stdout]         ROOM_NUMBER=?
[stdout] Hibernate: 
...
[ReservationEJB] *** ReservationEJB(12230192):destroy ***

  • Rejects checkin when invalid

  • Completes check-in when valid


  • Stateless EJB commits each of these check-ins


  • Additional check-in rejected -- nothing committed


  • Each check-in occured in own transaction

  • Later error did not impact previous completed transactions


  • Same stateful process as before -- but with one additional Guest (one too many)


  • Client attempts to check-in to all Rooms

  • Checked exception will be thrown


  • Five (5) Guests are flushed to database prior to the rollback


  • Persisted Guests removed from database as a part of transaction rollback

  • Early check-ins never flushed to DB -- discarded as part of rollback


  • All check-ins associated with Rooms removed as a part of rollback


  • setLockMode(LockModeType.PESSIMISTIC_WRITE) - locks row (or table) for remainder of transaction

  • select ... FOR UPDATE issued for query

  • competing client thread is blocked until end of transaction