Sophie

Sophie

distrib > Fedora > 17 > i386 > by-pkgid > 675c8c8167236dfcf8d66da674f931e8 > files > 458

erlang-doc-R15B-03.3.fc17.noarch.rpm

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html xmlns:fn="http://www.w3.org/2005/02/xpath-functions">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="../../../../doc/otp_doc.css" type="text/css">
<title>Erlang -- cosTransactions Examples</title>
</head>
<body bgcolor="white" text="#000000" link="#0000ff" vlink="#ff00ff" alink="#ff0000"><div id="container">
<script id="js" type="text/javascript" language="JavaScript" src="../../../../doc/js/flipmenu/flipmenu.js"></script><script id="js2" type="text/javascript" src="../../../../doc/js/erlresolvelinks.js"></script><script language="JavaScript" type="text/javascript">
            <!--
              function getWinHeight() {
                var myHeight = 0;
                if( typeof( window.innerHeight ) == 'number' ) {
                  //Non-IE
                  myHeight = window.innerHeight;
                } else if( document.documentElement && ( document.documentElement.clientWidth ||
                                                         document.documentElement.clientHeight ) ) {
                  //IE 6+ in 'standards compliant mode'
                  myHeight = document.documentElement.clientHeight;
                } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
                  //IE 4 compatible
                  myHeight = document.body.clientHeight;
                }
                return myHeight;
              }

              function setscrollpos() {
                var objf=document.getElementById('loadscrollpos');
                 document.getElementById("leftnav").scrollTop = objf.offsetTop - getWinHeight()/2;
              }

              function addEvent(obj, evType, fn){
                if (obj.addEventListener){
                obj.addEventListener(evType, fn, true);
                return true;
              } else if (obj.attachEvent){
                var r = obj.attachEvent("on"+evType, fn);
                return r;
              } else {
                return false;
              }
             }

             addEvent(window, 'load', setscrollpos);

             //--></script><div id="leftnav"><div class="innertube">
<img alt="Erlang logo" src="../../../../doc/erlang-logo.png"><br><small><a href="users_guide.html">User's Guide</a><br><a href="index.html">Reference Manual</a><br><a href="release_notes.html">Release Notes</a><br><a href="../pdf/cosTransactions-1.2.12.pdf">PDF</a><br><a href="../../../../doc/index.html">Top</a></small><p><strong>cosTransactions</strong><br><strong>User's Guide</strong><br><small>Version 1.2.12</small></p>
<br><a href="javascript:openAllFlips()">Expand All</a><br><a href="javascript:closeAllFlips()">Contract All</a><p><small><strong>Chapters</strong></small></p>
<ul class="flipMenu" imagepath="../../../../doc/js/flipmenu">
<li id="no" title="The cosTransactions Application" expanded="false">The cosTransactions Application<ul>
<li><a href="ch_contents.html">
              Top of chapter
            </a></li>
<li title="Content Overview"><a href="ch_contents.html#id61154">Content Overview</a></li>
<li title="Brief Description of the User's Guide"><a href="ch_contents.html#id57422">Brief Description of the User's Guide</a></li>
</ul>
</li>
<li id="no" title="Introduction to cosTransactions" expanded="false">Introduction to cosTransactions<ul>
<li><a href="ch_introduction.html">
              Top of chapter
            </a></li>
<li title="Overview"><a href="ch_introduction.html#id60972">Overview</a></li>
</ul>
</li>
<li id="no" title="Installing cosTransactions" expanded="false">Installing cosTransactions<ul>
<li><a href="ch_install.html">
              Top of chapter
            </a></li>
<li title="Installation Process "><a href="ch_install.html#id61216">Installation Process </a></li>
</ul>
</li>
<li id="loadscrollpos" title="cosTransactions Examples" expanded="true">cosTransactions Examples<ul>
<li><a href="ch_example.html">
              Top of chapter
            </a></li>
<li title="A Tutorial on How to Create a Simple Service"><a href="ch_example.html#id58308">A Tutorial on How to Create a Simple Service</a></li>
</ul>
</li>
<li id="no" title="Resource Skeletons" expanded="false">Resource Skeletons<ul>
<li><a href="ch_skeletons.html">
              Top of chapter
            </a></li>
<li title="Resource Skeletons"><a href="ch_skeletons.html#id56632">Resource Skeletons</a></li>
</ul>
</li>
</ul>
</div></div>
<div id="content">
<div class="innertube">
<h1>4 cosTransactions Examples</h1>
  

  <h3><a name="id58308">4.1 
        A Tutorial on How to Create a Simple Service</a></h3>
    

    <h4>Interface design</h4>
      
      <p>To use the cosTransactions application <strong>participants</strong> must be implemented. 
        There are two types of participants: </p>
      <ul>
        <li>
<span class="bold_code"><a href="CosTransactions_Resource.html">CosTransactions_Resource</a></span> - operations used to commit or rollback resources.</li>
        <li>
<span class="bold_code"><a href="CosTransactions_SubtransactionAwareResource.html">CosTransactions_SubtransactionAwareResource</a></span> - 
         operations used when the resources want to be notified when a subtransaction commits. 
         This interface inherits the CosTransactions_Resource</li>
      </ul>
      <p>The interfaces for these participants are defined in <strong>CosTransactions.idl</strong></p>
    

    <h4>Generating a Participant Interface</h4>
      
      <p>We start by creating an interface which inherits from <strong>CosTransactions::Resource</strong>. Hence, 
        we must also implement all operations defined in the Resource interface. The IDL-file could look like: </p>
      <div class="example"><pre>
#ifndef _OWNRESOURCEIMPL_IDL
#define _OWNRESOURCEIMPL_IDL
#include &lt;CosTransactions.idl&gt;

module ownResourceImpl {

  interface ownInterface:CosTransactions::Resource {

    void ownFunctions(in any NeededArguments)
       raises(Systemexceptions,OwnExceptions);

  };
};

#endif
      </pre></div>
      <p>Run the IDL compiler on this file by calling the <span class="code">ic:gen/1</span> function. 
        This will produce the API named <span class="code">ownResourceImpl_ownInterface.erl</span>.
        After generating the API stubs and the server skeletons it is time to 
        implement the servers and if no special options are sent 
        to the IDl compiler the file name is <span class="code">ownResourceImpl_ownInterface_impl.erl</span>.</p>
    

    <h4>Implementation of Participant interface</h4>
      
      <p>If the participant is intended to be a plain Resource, we must implement the following operations:</p>
      <ul>
        <li>
<span class="code">prepare/1</span> - this operation is invoked on the Resource to begin the two-phase commit protocol.</li>
        <li>
<span class="code">rollback/1</span> - this operation instructs the Resource to rollback all changes made as a part of the transaction. </li>
        <li>
<span class="code">commit/1</span> - this operation instructs the Resource to commit all changes made as a part of the transaction.</li>
        <li>
<span class="code">commit_one_phase/1</span> - if possible, the Resource should commit all changes made as part of the transaction. 
         This operation can only be used if the Resource is the only child of its parent. </li>
        <li>
<span class="code">forget/1</span> - this operation informs the Resource that it is safe to forget any 
        Heuristic decisions
              and the knowledge of the transaction.</li>
        <li>
<span class="code">ownFunctions</span> - all application specific operations.</li>
      </ul>
      <p>If the participant wants to be notified when a subtransaction commits, we must also implement the following operations 
        (besides the operations above):</p>
      <ul>
        <li>
<span class="code">commit_subtransaction/2</span> - if the <span class="code">SubtransactionAwareResource</span> have been registered 
         with a transactions using the operation <span class="code">CosTransactions_Coordinator:register_subtran_aware/2</span> it will 
         be notified when the transaction has
         committed. </li>
        <li>
<span class="code">rollback_subtransaction/1</span> - if the <span class="code">SubtransactionAwareResource</span> have been registered 
         with a transactions using the operation <span class="code">CosTransactions_Coordinator:register_subtran_aware/2</span>
         it will be notified when the transaction has
         rolled back. </li>
      </ul>
      <div class="note">
<div class="label">Note</div>
<div class="content"><p>
        <p>The results of a committed subtransaction are relative to the completion of its ancestor transactions, 
          that is, these results can be undone if any ancestor transaction is rolled back. </p>
      </p></div>
</div>
    

    <h4>Participant Operations Behavior</h4>
      
      <p>Each application participant must behave in a certain way to ensure that the two-phase commit protocol
        can complete the transactions correctly.</p>

      <h4>prepare</h4>
        
        <p>This operation ask the participant to vote on the outcome of the transaction. Possible replies are:</p>
        <ul>
          <li>
<strong>'VoteReadOnly'</strong> - if no data associated with the transaction has been modified VoteReadOnly may be returned.
           The Resource can forget all knowledge of the transaction and terminate.</li>
          <li>
<strong>'VoteCommit'</strong> - if the Resource is able to write all the data needed to commit the transaction to a stable storage,
           VoteCommit may be returned. The Resource will then wait until it is informed of the outcome of the transaction.
           The Resource may, however, make a unilateral decision (Heuristic) to commit or rollback changes associated 
           with the transaction. When the Resource is informed of the true outcome (rollback/commit) and it is equal to
           the Heuristic decision the Resource just return 'ok'. But, if there is a mismatch and the commit-operation is irreversible,
           the Resource must raise a <span class="bold_code"><a href="CosTransactions_Resource.html">Heuristic Exception</a></span> and wait 
           until the <span class="code">forget</span> operation is invoked. The Heuristic Decision must be recorded in stable storage.</li>
          <li>
<strong>'VoteRollback'</strong> - the Resource may vote VoteRollback under any circumstances.
           The Resource can forget all knowledge of the transaction and terminate.</li>
        </ul>
        <div class="note">
<div class="label">Note</div>
<div class="content"><p>
          <p>Before replying to the prepare operation, the Resource must record the prepare state, the reference of its
            superior <span class="bold_code"><a href="CosTransactions_RecoveryCoordinator.html">RecoveryCoordinator</a></span> in stable storage.
            The RecoveryCoordinator is obtained when registering as a participant in a transaction.</p>
        </p></div>
</div>
      

      <h4>rollback</h4>
        
        <p>The Resource should, if necessary, rollback all changes made as part of the transaction. If the Resource is not aware of the
          transaction it should do nothing, e.g., recovered after a failure and have no data in stable storage. Heuristic Decisions
          must be handled as described above.</p>
      

      <h4>commit</h4>
        
        <p>The Resource should, if necessary, commit all changes made as part of the transaction. If the Resource is not aware of the
          transaction it should do nothing, e.g., recovered after a failure and have no data in stable storage. Heuristic Decisions
          must be handled as described above.</p>
      

      <h4>commit_one_phase</h4>
        
        <p>If possible, the Resource should commit all changes made as part of the transaction. If it cannot, it should raise the
          TRANSACTION_ROLLEDBACK exception. This operation can only be used if the Resource is the only child of its parent.
          If a failure occurs the completion of the operation must be retried when the failure is repaired. Heuristic Decisions
          must be handled as described above.</p>
      

      <h4>forget</h4>
        
        <p>If the Resource raised a Heuristic Exception to <span class="code">commit</span>, <span class="code">rollback</span> or <span class="code">commit_one_phase</span> this operation
          will be performed. The Resource can forget all knowledge of the transaction and terminate.</p>
      

      <h4>commit_subtransaction</h4>
        
        <p>If the <span class="code">SubtransactionAwareResource</span> have been registered with a <strong>subtransaction</strong>
          using the operation <span class="code">CosTransactions_Coordinator:register_subtran_aware/2</span>
          it will be notified when the transaction has committed. The Resource may raise the exception
          <span class="code">'TRANSACTION_ROLLEDBACK'</span>.</p>
        <div class="note">
<div class="label">Note</div>
<div class="content"><p>
          <p>The result of a committed subtransaction is relative to the completion of its ancestor
            transactions, that is, these results can be undone if any ancestor transaction is rolled back.</p>
        </p></div>
</div>
      

      <h4>rollback_subtransaction</h4>
        
        <p>If the <span class="code">SubtransactionAwareResource</span> have been registered with a <strong>subtransaction</strong>
          using the operation <span class="code">CosTransactions_Coordinator:register_subtran_aware/2</span>
          it will be notified when the subtransaction has rolled back.</p>
      
    

    <h4>How to Run Everything</h4>
      
      <p>Below is a short transcript on how to run cosTransactions. </p>
      <div class="example"><pre>

%% Start Mnesia and Orber
mnesia:delete_schema([node()]),
mnesia:create_schema([node()]),
orber:install([node()]),
application:start(mnesia),
application:start(orber),

%% Register CosTransactions in the IFR.
'oe_CosTransactions':'oe_register'(), 

%% Register the application specific Resource implementations
%% in the IFR.
'oe_ownResourceImpl':'oe_register'(), 

%%-- Set parameters --
%% Timeout can be either 0 (no timeout) or an integer N &gt; 0.
%% The later state that the transaction should be rolled 
%% back if the transaction have not completed within N seconds.
TimeOut = 0,

%% Do we want the transaction to report Heuristic Exceptions?
%% This variable must be boolean and indicates the way the
%% Terminator should behave.
Heuristics = true,

%% Start the cosTransactions application.
cosTransactions:start(),  %% or application:start(cosTransactions),

%% Start a factory using the default configuration
TrFac = cosTransactions:start_factory(),
%% ... or use configuration parameters.
TrFac = cosTransactions:start_factory([{typecheck, false}, {hash_max, 3013}]),

%% Create a new top-level transaction.
Control = 'CosTransactions_TransactionFactory':create(TrFac, TimeOut),

%% Retrieve the Coordinator and Terminator object references from
%% the Control Object.
Term = 'CosTransactions_Control':get_terminator(Control),
Coord = 'CosTransactions_Control':get_coordinator(Control),

%% Create two SubTransactions with the root-Coordinator as parent.
SubCont1 = 'CosTransactions_Coordinator':create_subtransaction(Coord),
SubCont2 = 'CosTransactions_Coordinator':create_subtransaction(Coord),

%% Retrieve the Coordinator references from the Control Objects.
SubCoord1 = 'CosTransactions_Control':get_coordinator(SubCont1),
SubCoord2 = 'CosTransactions_Control':get_coordinator(SubCont2),

%% Create application Resources. We can, for example, start the Resources 
%% our selves or look them up in the naming service. This is application
%% specific.
Res1 = ...
Res2 = ...
Res3 = ...
Res4 = ...

%% Register Resources with respective Coordinator. Each call returns
%% a RecoveryCoordinator object reference.
RC1 = 'CosTransactions_Coordinator':register_resource(SubCoord1, Res1),
RC2 = 'CosTransactions_Coordinator':register_resource(SubCoord1, Res2),
RC3 = 'CosTransactions_Coordinator':register_resource(SubCoord2, Res3),
RC4 = 'CosTransactions_Coordinator':register_resource(SubCoord2, Res4),

%% Register Resource 4 with SubCoordinator 1 so that the Resource will be 
%% informed when the SubCoordinator commits or roll-back.
'CosTransactions_Coordinator':register_subtran_aware(SubCoord1, Res4),

%% We are now ready to try to commit the transaction. The second argument
%% must be a boolean
Outcome = (catch 'CosTransactions_Terminator':commit(Term, Heuristics)),
      </pre></div>
      <div class="note">
<div class="label">Note</div>
<div class="content"><p>
        <p>For the cosTransaction application to be able to recognize if a Resource is
          dead or in the process of restarting the Resource must be started as persistent,
          e.g., 'OwnResource':oe_create_link(Env, [{regname, {global, RegName}}, {persistent, true}]).
          For more information see the Orber documentation.</p>
      </p></div>
</div>
      <p>The outcome of the transaction can be:</p>
      <ul>
        <li>ok - the transaction was successfully committed.</li>
        <li>{'EXCEPTION', HeuristicExc} - at least one participant made a
         Heuristic decision or, due to a failure, one or more participants
         where unreachable.</li>
        <li>{'EXCEPTION', #'TRANSACTION_ROLLEDBACK'{}} - 
         the transaction was successfully rolled back.</li>
        <li>Any system exception - 
         the transaction failed with unknown reason.</li>
      </ul>
    
  
</div>
<div class="footer">
<hr>
<p>Copyright © 1999-2012 Ericsson AB. All Rights Reserved.</p>
</div>
</div>
</div></body>
</html>