<document>
  <header>
    <product>resin-ee</product>
    <resin-2.0>$ee/ejb-tut/cmp-basic-transaction.xtp</resin-2.0>
    <title>CMP Basic Transactions</title>
    <type>tutorial</type>
    <tutorial-startpage>register</tutorial-startpage>
  </header>

  <body>
    <summary/>

<p>Transactions are a concept simple to use and hard to implement.
Fortunately, Resin-CMP has done the implementation for you.  Transactions
work like a sophisticated lock or synchronize block.  Either everything in
a transaction completes or none of it does.</p>

<p>The example is the same as the <a href="../cmp-basic/index.xtp">CMP basic</a>
example with the additional twist that we'll swap the instructors for
two courses.</p>

<p>If we were to write the code ignoring transactions, it would look like:</p>

<example title="Unsafe Swap">
Course course1 = courseHome.findByPrimaryKey("Potions");
Course course2 = courseHome.findByPrimaryKey("Transfiguration");

String temp = course1.getInstructor();
course1.setInstructor(course2.getInstructor());
course2.setInstructor(temp);
</example>

<p>But that code is unsafe if two clients try to swap at once.  The
following is a possible sequence of two clients, resulting in a
non-sensical database configuration:</p>

<deftable>
<tr><th>Thread 1<th>Thread 2
<tr><td width='50%'>temp = 'McGonagall'<td>&nbsp;
<tr><td>c1.setInstructor('Snape')<td>&nbsp;
<tr><td>&nbsp;<td>temp = 'Snape'
<tr><td>&nbsp;<td>c1.setInstructor('Snape')
<tr><td>c2.setInstructor('McGonagall')<td>&nbsp;
<tr><td>&nbsp;<td>c2.setInstructor('Snape')
</deftable>

<p>If the above sequence ever happened, Snape would be teaching
both classes.  Transactions can avoid that inconsistency.</p>

<section title="Demo">
  <a href="register">Demo</a>
</section>

<section title='User Transactions'>

<p>The consistency problem can be solved with user transactions or
by encapsulating the swap in a bean's business methods.  Although
encapsulation is a better choice in general, we'll introduce
<code/UserTransaction/> first because it better shows what's going on.</p>

<p>The <code/UserTransaction/> interface (in <code/javax.transaction/>)
lets you
control transactions from the client code.  You can get access to the
UserTransaction object through the JNDI path
<code/java:comp/UserTransaction/>.</p>

<p><code/UserTransaction/> works like a synchronized lock.  You start the
transaction with <code/begin()/> and complete the transaction
with <code/commit()/>.  You must always either commit or
<code/rollback()/> the transaction.  So put it in a finally block.</p>

<example title="UserTransaction Swap">
Context ic = new InitialContext();

UserTransaction trans =
 (UserTransaction) ic.lookup("java:comp/UserTransaction");

try {
  trans.begin()

  String temp = course1.getInstructor();
  course1.setInstructor(course2.getInstructor());
  course2.setInstructor(temp);
} finally {
  trans.commit();
}
</example>

<p>One thing to be aware of: transactions can throw exceptions.  The database
will always be consistent, but it's possible that your commit() call
will fail and throw an exception.  The entire transaction will be
rolled back as if it never happened.  So your database is safe, but
your client code should have some error recovery.
</p>

<p>The common reasons for the transaction to fail is if two threads
try to change the same database record at the same time.  This can
cause a temporary deadlock as both threads have read locks and both
try to get write locks at the same time.  One of the threads will win
and the other will lose.  The loser will get a thrown exception.
</p>

</section>

<section title='Entity Business Methods'>

<p>The better solution is to encapsulate all state changes in entity
business methods.  Resin-CMP will automatically generate the
transaction code for you, saving a little bit of time, but more
importantly avoiding bugs.  You'll add a business method to the local
interface and to the bean implementation:</p>

<example title="Course.java">
package example.cmp.basic;

import javax.ejb.*;

public interface Course extends EJBLocalObject {
  String getCourseId();

  String getInstructor();
  void setInstructor(String instructor);

  void swap(Course course);
}
</example>

<example title="CourseBean.java">
package example.cmp.basic;

public abstract class CourseBean
  extends com.caucho.ejb.AbstractEntityBean {
  public abstract String getCourseId();

  public abstract String getInstructor();
  public abstract void setInstructor(String val);

  public void swap(Course course)
  {
    String temp = getInstructor();
    setInstructor(course.getInstructor());
    course.setInstructor(temp);
  }
}
</example>

<p>Every call to <code/Course.swap/> will automatically be wrapped
in a transaction.  So the database will be updated cleanly and
consistently and the client code can avoid using <code/UserTransaction/>.</p>

</section>
  </body>
</document>
