<?xml version="1.0" encoding="UTF-8"?>
<section version="5.0" 
         xmlns="http://docbook.org/ns/docbook" 
         xmlns:xlink="http://www.w3.org/1999/xlink" 
         xmlns:xi="http://www.w3.org/2001/XInclude" 
         xmlns:svg="http://www.w3.org/2000/svg" 
         xmlns:mml="http://www.w3.org/1998/Math/MathML" 
         xmlns:html="http://www.w3.org/1999/xhtml" 
         xmlns:db="http://docbook.org/ns/docbook" 
         xml:lang="en" 
         xml:id="ejb2.transaction">

  <info><title>EJB2 Transactional Behaviour</title></info>
  
  <section xml:id="ejb2.transaction.declarative"><info><title>Declarative Transaction Management</title></info>
    
    <para>
      For container-managed transaction management, the transactional behaviour of an enterprise bean is defined at configuration time and is part of the assembly-descriptor element of the standard deployment descriptor. It is possible to define a common behaviour for all the methods of the bean, or to define the behaviour at the method level. This is done by specifying a transactional attribute, which can be one of the following:
    </para>
    <itemizedlist>
      <listitem><para>
        NotSupported:
         if the method is called within a     transaction, this transaction is suspended during the time of the method     execution.
      </para></listitem>
      <listitem><para>
        Required
        : if the method is called within a     transaction, the method is executed in the scope of this transaction,     else, a new transaction is started for the execution of the method, and     committed before the method result is sent to the caller.
      </para></listitem>
      <listitem><para>
        RequiresNew
        : the method will always be executed within     the scope of a new transaction. The new transaction is started for the     execution of the method, and committed before the method result is sent     to the caller. If the method is called within a transaction, this     transaction is suspended before the new one is started and resumed when     the new transaction has completed.
      </para></listitem>
      <listitem><para>
        Mandatory
        : the method should always be called within     the scope of a transaction, else the container will throw the     
        TransactionRequired
         exception.
      </para></listitem>
      <listitem><para>
        Supports
        : the method is invoked within the caller     transaction scope; if the caller does not have an associated transaction,     the method is invoked without a transaction scope.
      </para></listitem>
      <listitem><para>
        Never
        : The client is required to call the bean without     any transaction context; if it is not the case, a     java.rmi.RemoteException is thrown by the container.
      </para></listitem>
    </itemizedlist><para>
     This is illustrated in the following table:</para>  
    <informaltable>
      <tgroup cols="3">
        <thead>
          <row>
            <entry>
              Transaction Attribute
            </entry>
            <entry>
              Client transaction
            </entry>
            <entry>
              Transaction associated with enterprise Bean method
            </entry>
          </row>
        </thead>
        <tbody>
          <row>
            <entry morerows="1" valign="middle">NotSupported</entry>
            <entry>-</entry>  
            <entry>-</entry> 
          </row>    
          <row>  
            <entry>T1</entry>
            <entry>-</entry>
          </row>
          <row>
            <entry morerows="1" valign="middle">Required</entry>
            <entry>-</entry>  
            <entry>T2</entry> 
          </row>    
          <row>  
            <entry>T1</entry>
            <entry>T1</entry>
          </row>
          <row>
            <entry morerows="1" valign="middle">RequiresNew</entry>
            <entry>-</entry>  
            <entry>T2</entry> 
          </row>    
          <row>  
            <entry>T1</entry>
            <entry>T2</entry>
          </row>
          <row>
            <entry morerows="1" valign="middle">Mandatory</entry>
            <entry>-</entry>  
            <entry>ERROR</entry> 
          </row>    
          <row>  
            <entry>T1</entry>
            <entry>T1</entry>
          </row>
          <row>
            <entry morerows="1" valign="middle">Supports</entry>
            <entry>-</entry>  
            <entry>-</entry> 
          </row>    
          <row>  
            <entry>T1</entry>
            <entry>T1</entry>
          </row>
          <row>
            <entry morerows="1" valign="middle">Never</entry>
            <entry>-</entry>  
            <entry>-</entry> 
          </row>    
          <row>  
            <entry>T1</entry>
            <entry>ERROR</entry>
          </row>
        </tbody>
      </tgroup>
    </informaltable>
    <para>
      In the deployment descriptor, the specification of the transactional attributes appears in the assembly-descriptor as follows:
    </para>
    <screen>
  &lt;assembly-descriptor&gt;
    &lt;container-transaction&gt;
      &lt;method&gt;
      &lt;ejb-name&gt;AccountImpl&lt;/ejb-name&gt;
      &lt;method-name&gt;*&lt;/method-name&gt;
      &lt;/method&gt;
      &lt;trans-attribute&gt;Supports&lt;/trans-attribute&gt;
    &lt;/container-transaction&gt;
    &lt;container-transaction&gt;
      &lt;method&gt;
      &lt;ejb-name&gt;AccountImpl&lt;/ejb-name&gt;
      &lt;method-name&gt;getBalance&lt;/method-name&gt;
      &lt;/method&gt;
      &lt;trans-attribute&gt;Required&lt;/trans-attribute&gt;
    &lt;/container-transaction&gt;
    &lt;container-transaction&gt;
      &lt;method&gt;
      &lt;ejb-name&gt;AccountImpl&lt;/ejb-name&gt;
      &lt;method-name&gt;setBalance&lt;/method-name&gt;
      &lt;/method&gt;
      &lt;trans-attribute&gt;Mandatory&lt;/trans-attribute&gt;
    &lt;/container-transaction&gt;
  &lt;/assembly-descriptor&gt;
    
    </screen>
    <para>
      In this example, for all methods of the AccountImpl bean which are not explicitly specified in a container-transaction element, the default transactional attribute is Supports (defined at the bean-level), and the transactional attributes are Required and Mandatory (defined at the method-name level) for the methods getBalance and setBalance respectively.
    </para>
  </section>
  <section xml:id="ejb2.transactiopn.bmt"><info><title>Bean-managed Transaction</title></info>
    
    <para>
      A bean that manages its transactions itself must set the 
      <literal>
        transaction-type
      </literal>
       element in its standard deployment descriptor to:
    </para>
    <screen>
  &lt;transaction-type&gt;Bean&lt;/transaction-type&gt;
    
    </screen>
    <para>
      To demarcate the transaction boundaries in a bean with bean-managed transactions, the bean programmer should use the 
      javax.transaction.UserTransaction
       interface, which is defined on an EJB server object that may be obtained using the 
      EJBContext.getUserTransaction()
       method (the SessionContext object or the EntityContext object depending on whether the method is defined on a session or on an entity bean). The following example shows a session bean method "doTxJob" demarcating the transaction boundaries; the UserTransaction object is obtained from the sessionContext object, which should have been initialized in the setSessionContext method (refer to the 
      <link xlink:href="ejb2_programmer_guide.html#ejb2.session.example">
        example of the session bean
      </link>
      ).
    </para>
    <screen>
public void doTxJob() throws  RemoteException {
     UserTransaction ut = sessionContext.getUserTransaction();
     ut.begin();
     ... // transactional operations
     ut.commit();
}
    </screen>
    <para>
      Another way to do this is to use JNDI and to retrieve UserTransaction with the name 
      <literal>
        java:comp/UserTransaction
      </literal>
       in the initial context.
    </para>
  </section>
  <section xml:id="ejb2.transaction.distributed"><info><title>Distributed Transaction Management</title></info>
    
    <para>
      As explained in the previous section, the transactional behaviour of an application can be defined in a declarative way or coded in the bean and/or the client itself (transaction boundaries demarcation). In any case, the distribution aspects of the transactions are completely transparent to the bean provider and to the application assembler. This means that a transaction may involve beans located on several JOnAS servers and that the platform itself will handle management of the global transaction. It will perform the two-phase commit protocol between the different servers, and the bean programmer need do nothing.
    </para>
    <para>
      Once the beans have been developed and the application has been assembled, it is possible for the deployer and for the administrator to configure the distribution of the different beans on one or several machines, and within one or several JOnAS servers. This can be done without impacting either the beans code or their deployment descriptors. The distributed configuration is specified at launch time. In the environment properties of an EJB server, the following can be specified:
    </para>
    <itemizedlist>
      <listitem><para>
        which enterprise beans the JOnAS server will handle,
      </para></listitem>
      <listitem><para>
        if a Java Transaction Monitor will be located in the same Java Virtual     Machine (JVM) or not.
      </para></listitem>
    </itemizedlist>
    <para>
      To achieve this goal, two properties must be set in the 
       jonas.properties
       file, 
      jonas.service.ejb.descriptors
       and 
      jonas.service.jtm.remote
      . The first one lists the beans that will be handled on this server (by specifying the name of their ejb-jar files), and the second one sets the Java Transaction Monitor (JTM) launching mode:
    </para>
    <itemizedlist>
      <listitem><para>
        if set to 
        <literal>
          true
        </literal>
        , the JTM is remote, i.e. the JTM must be     launched previously in another JVM,
      </para></listitem>
      <listitem><para>
        if set to 
        <literal>
          false
        </literal>
        , the JTM is local, i.e. it will run in the     same JVM as the EJB Server.
      </para></listitem>
    </itemizedlist>
    <para>
      Example:
    </para>
    <screen>
  jonas.service.ejb.descriptors       Bean1.jar, Bean2.jar
  jonas.service.jtm.remote            false
    
    </screen>
    <para>
      Using these configuration facilities, it is possible to adapt the beans distribution to the resources (cpu and data) location, for optimizing performance.
    </para>
    <para>
      The following figure illustrates four cases of distribution configuration for three beans.
    </para>
    <para>
      <mediaobject>
        <imageobject>
          <imagedata fileref="../../../../resources/images/WP_distr.gif" width="450" depth="337"><info><othercredit otherclass="srccredit" class="other"><orgname>???</orgname><contrib>Figure illustrating beans distr</contrib></othercredit></info></imagedata>
        </imageobject>
      </mediaobject>
    </para>
    <orderedlist>
      <listitem><para>
        Case 1: The three beans B1, B2, and B3 are located on the same JOnAS     server, which embeds a Java Transaction Monitor.
      </para></listitem>
      <listitem><para>
        Case 2: The three beans are located on different JOnAS servers, one of     them running the Java Transaction Monitor, which manages the global     transaction.
      </para></listitem>
      <listitem><para>
        Case 3: The three beans are located on different JOnAS servers, the     Java Transaction Monitor is running outside of any JOnAS server.
      </para></listitem>
      <listitem><para>
        Case 4: The three beans are located on different JOnAS servers. Each     server is running a Java Transaction Monitor. One of the JTM acts as the     master monitor, while the two others are slaves.
      </para></listitem>
    </orderedlist>
    <para>
      These different configuration cases may be obtained by launching the JOnAS servers and eventually the JTM (case 3) with the adequate properties. The rational when choosing one of these configurations is resources location and load balancing. However, consider the following pointers:
    </para>
    <itemizedlist>
      <listitem><para>
        if the beans should run on the same machine, with the same server     configuration, case 1 is the more appropriate;
      </para></listitem>
      <listitem><para>
        if the beans should run on different machines, case 4 is the more     appropriate, since it favours local transaction management;
      </para></listitem>
      <listitem><para>
        if the beans should run on the same machine, but require different     server configurations, case 2 is a good approach.
      </para></listitem>
    </itemizedlist>
  </section>
</section>