Show Table of Contents

21.9. Transactions
All of the examples presented in this chapter have been defined to run in a transaction. Transaction granularity is a dominating factor in optimized loading because transactions define the lifetime of preloaded data. If the transaction completes, commits, or rolls back, the data in the preload cache is lost. This can result in a severe negative performance impact.
The performance impact of running without a transaction will be demonstrated with an example that uses an
on-find optimized query that selects the first four gangsters (to keep the result set small), and it is executed without a wrapper transaction. The example code follows:
public String createGangsterHtmlTable_no_tx() throws FinderException
{
StringBuffer table = new StringBuffer();
table.append("<table>");
Collection gangsters = gangsterHome.findFour();
for(Iterator iter = gangsters.iterator(); iter.hasNext(); ) {
Gangster gangster = (Gangster)iter.next();
table.append("<tr>");
table.append("<td>").append(gangster.getName());
table.append("</td>");
table.append("<td>").append(gangster.getNickName());
table.append("</td>");
table.append("<td>").append(gangster.getBadness());
table.append("</td>");
table.append("</tr>");
}
table.append("</table>");
return table.toString();
}
The finder results in the following query being executed:
SELECT t0_g.id, t0_g.name, t0_g.nick_name, t0_g.badness FROM gangster t0_g WHERE t0_g.id < 4 ORDER BY t0_g.id ASC
Normally this would be the only query executed, but since this code is not running in a transaction, all of the preloaded data is thrown away as soon as finder returns. Then when the CMP field is accessed JBoss executes the following four queries (one for each loop):
SELECT id, name, nick_name, badness FROM gangster WHERE (id=0) OR (id=1) OR (id=2) OR (id=3) SELECT id, name, nick_name, badness FROM gangster WHERE (id=1) OR (id=2) OR (id=3) SELECT id, name, nick_name, badness FROM gangster WHERE (id=2) OR (id=3) SELECT name, nick_name, badness FROM gangster WHERE (id=3)
It's actually worse than this. JBoss executes each of these queries three times; once for each CMP field that is accessed. This is because the preloaded values are discarded between the CMP field accessor calls.
The following figure shows the execution of the queries:

Figure 21.13. No Transaction on-find optimized query execution
This performance is much worse than read ahead none because of the amount of data loaded from the database. The number of rows loaded is determined by the following equation:

This all happens because the transaction in the example is bounded by a single call on the entity. This brings up the important question "How do I run my code in a transaction?" The answer depends on where the code runs. If it runs in an EJB (session, entity, or message driven), the method must be marked with the
Required or RequiresNewtrans-attribute in the assembly-descriptor. If the code is not running in an EJB, a user transaction is necessary. The following code wraps a call to the declared method with a user transaction:
public String createGangsterHtmlTable_with_tx()
throws FinderException
{
UserTransaction tx = null;
try {
InitialContext ctx = new InitialContext();
tx = (UserTransaction) ctx.lookup("UserTransaction");
tx.begin();
String table = createGangsterHtmlTable_no_tx();
if (tx.getStatus() == Status.STATUS_ACTIVE) {
tx.commit();
}
return table;
} catch (Exception e) {
try {
if (tx != null) tx.rollback();
} catch (SystemException unused) {
// eat the exception we are exceptioning out anyway
}
if (e instanceof FinderException) {
throw (FinderException) e;
}
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
}
throw new EJBException(e);
}
}

Where did the comment section go?
Red Hat's documentation publication system recently went through an upgrade to enable speedier, more mobile-friendly content. We decided to re-evaluate our commenting platform to ensure that it meets your expectations and serves as an optimal feedback mechanism. During this redesign, we invite your input on providing feedback on Red Hat documentation via the discussion platform.