SE 452 Lecture Notes


Week 9: More Struts & Transactions



Administrative [1/29]
ActionForms [2/29]
org.apache.struts.action.DynaActionForm and Mapped Backed Beans [3/29]
ActionMappings [4/29]
Action [5/29]
Tag Libs [6/29]
Java Transaction Service [7/29]
Why do we need transactions? [8/29]
A demonstration of the risk [9/29]
What's the solution [10/29]
ACID Properties[11/29]
Anatomy of a transaction [12/29]
The transaction log [13/29]
Two-phase commit [14/29]
Transactions hide exception-handling and synchronization from us [15/29]
J2EE, JTS, and Other Acronyms [16/29]
Transparent resource enlistment [17/29]
Transparent resource enlistment II [18/29]
Transparent transaction propagation [19/29]
Optimization [20/29]
Demarcation [21/29]
Bean Managed vs. Container Managed [22/29]
Get in, get out [23/29]
Group related operations together [24/29]
trans-attribute tag revisited [25/29]
Container Managed Transaction Lifecycle [26/29]
Choosing a transaction mode [27/29]
Database Isolation Levels [28/29]
Concurrency Hazards [29/29]

Administrative [1/29]




ActionForms [2/29]



Today we'll spend a bit of time confirming our understanding of the Struts framework, w/ a bit more detail. Then we'll go onto a more advanced topic of transactions, which will segway some of you nicely into EJBs.


org.apache.struts.action.DynaActionForm and Mapped Backed Beans [3/29]



ActionMappings [4/29]



Action [5/29]


ActionErrors errors = new ActionErrors(); try { // call business layer } catch(ModelException e) { errors.add(ActionErrors.GLOBAL_ERROR, new ActionError("error.detail", e.getMessage())); } if(!errors.empty) { saveErrors(request, errors); return mapping.findForward("error"); }

Tag Libs [6/29]



Java Transaction Service [7/29]



Why do we need transactions? [8/29]



A demonstration of the risk [9/29]



SELECT accountBalance INTO aBalance
    FROM Accounts WHERE accountId=aId;
IF (aBalance >= transferAmount) THEN
    UPDATE Accounts
        SET accountBalance = accountBalance - transferAmount
        WHERE accountId = aId;
    UPDATE Accounts
        SET accountBalance = accountBalance + transferAmount
        WHERE accountId = bId;
    INSERT INTO AccountJournal (accountId, amount)
        VALUES (aId, -transferAmount);
    INSERT INTO AccountJournal (accountId, amount)
        VALUES (bId, transferAmount);
ELSE
    FAIL "Insufficient funds in account";
END IF

What's the solution [10/29]



ACID Properties [11/29]



Anatomy of a transaction [12/29]



The transaction log [13/29]



Two-phase commit [14/29]



Transactions hide exception-handling and synchronization from us [15/29]



public boolean copyFile(String inFile, String outFile) {
  InputStream is = null;
  OutputStream os = null;
  byte[] buffer;
  boolean success = true;

  try {
    is = new FileInputStream(inFile);
    os = new FileOutputStream(outFile);
    buffer = new byte[is.available()];
    is.read(buffer);
    os.write(buffer);
  }
  catch {IOException e) {
    success = false;
  }
  catch (OutOfMemoryError e) {
    success = false;
  }
  finally {
    if (is != null)
      is.close();
    if (os != null)
      os.close();
  }

  return success;
}

J2EE, JTS, and Other Acronyms [16/29]



Transparent resource enlistment [17/29]



  InitialContext ic = new InitialContext();
  UserTransaction ut = ejbContext.getUserTransaction();
  ut.begin();

  DataSource db1 = (DataSource) ic.lookup("java:comp/env/OrdersDB");
  DataSource db2 = (DataSource) ic.lookup("java:comp/env/InventoryDB");
  Connection con1 = db1.getConnection();
  Connection con2 = db2.getConnection();
  // perform updates to OrdersDB using connection con1
  // perform updates to InventoryDB using connection con2
  ut.commit();

Transparent resource enlistment II [18/29]



<assembly-descriptor>
  ...
  <container-transaction>
    <method>
      <ejb-name>MyBean</ejb-name>
      <method-name>*</method-name>
    </method>
    <trans-attribute>Required</trans-attribute>
  </container-transaction>
  <container-transaction>
    <method>
      <ejb-name>MyBean</ejb-name>
      <method-name>updateName</method-name>
      </method>
   <trans-attribute>RequiresNew</trans-attribute>
  </container-transaction>
  ...
</assembly-descriptor>

Transparent transaction propagation [19/29]



Optimization [20/29]



Demarcation [21/29]



Bean Managed vs. Container Managed [22/29]



Get in, get out [23/29]


Should you retrieve some data from a database, display the data, and then ask the user to make a choice while still in the transaction?

Group related operations together [24/29]



SELECT accountBalance INTO aBalance
    FROM Accounts WHERE accountId=aId;
IF (aBalance >= transferAmount) THEN
    UPDATE Accounts
        SET accountBalance = accountBalance - transferAmount
        WHERE accountId = aId;
    UPDATE Accounts
        SET accountBalance = accountBalance + transferAmount
        WHERE accountId = bId;
    INSERT INTO AccountJournal (accountId, amount)
        VALUES (aId, -transferAmount);
    INSERT INTO AccountJournal (accountId, amount)
        VALUES (bId, transferAmount);
ELSE
    FAIL "Insufficient funds in account";
END IF

Rule of Thumb: Group related operations into a single transaction, but put unrelated operations into separate transactions


trans-attribute tag revisited [25/29]


Six Transaction Modes
Transaction mode Bean types Action when called in transaction T Action when called outside of a transaction
Required Session, Entity, Message-driven Enlist in T New transaction
RequiresNew Session, Entity New transaction New transaction
Supports Session, Message-driven Enlist in T Run without transaction
Mandatory Session, Entity Enlist in T Error
NotSupported Session, Message-driven Run without transaction Run without transaction
Never Session, Message-driven Error Run without transaction

Container Managed Transaction Lifecycle [26/29]



Choosing a transaction mode [27/29]



You need to analyze every situation, but here are some rules of thumb

J2EE architecture encourages decomposition of the application into the smallest convenient processing chunks, and each chunk is processed as an individual request (whether in the form of an HTTP request or as the result of a message being queued to a JMS queue). If you architect this way the Required tag should be less costly.


Database Isolation Levels [28/29]


  • Isolation: to mean that the effects of one transaction are not visible to other transactions executing concurrently; from the perspective of a transaction, it appears that transactions execute sequentially rather than in parallel
  • Transactional resource managers can often process many transactions simultaneously while providing the illusion of isolation
  • Sometimes isolation constraints actually require that beginning a new transaction be deferred until an existing transaction completes
  • Since completing a transaction involves at least one synchronous disk I/O (to write to the transaction log), this could limit the number of transactions per second to something close to the number of disk writes per second, which would not be good for scalability
  • We relax these levels in practice
  • DBs support four levels of Isolation
    1. Read Uncommitted
    2. Read committed
    3. Repeatable Read
    4. Serializable
  • J2EE does not require support for isolation levels for container-managed transactions, although Websphere and Weblogic provide it
  • bean-managed transactions, you can set isolation levels via the JDBC or other resource manager connection

    Concurrency Hazards [29/29]



    --concurrency hazards -- cases where one transaction might interfere with another in the absence of suitable isolation
    --All of the following hazards have to do with the results of one transaction becoming visible to a second transaction after the second transaction has already started:
      Dirty Read Non-Repeatable Read Phantom Read
    Read uncommitted Possible Possible Possible
    Read committed Not possible Possible Possible
    Repeatable read Not possible Not possible Possible
    Serializable Not possible Not possible Not possible





    Reading of interest
  • The Java Transaction Service specification is quite readable and offers a high-level explanation of how an object transaction monitor fits into distributed applications.

  • The lower-level details of transactional support in J2EE is detailed in the Java Transaction API (JTA) specification.