1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- This document was generated using DocBuilder 3.3.3 -->
<HTML>
<HEAD>
<TITLE>cosTransactions Examples</TITLE>
<SCRIPT type="text/javascript" src="../../../../doc/erlresolvelinks.js">
</SCRIPT>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#FF00FF"
ALINK="#FF0000">
<CENTER>
<A HREF="http://www.erlang.se"><IMG BORDER=0 ALT="[Ericsson AB]" SRC="min_head.gif"></A>
</CENTER>
<A NAME="4"><!-- Empty --></A>
<H2>4 cosTransactions Examples</H2>
<A NAME="4.1"><!-- Empty --></A>
<H3>4.1 A Tutorial on How to Create a Simple Service</H3>
<A NAME="4.1.1"><!-- Empty --></A>
<H4>4.1.1 Interface design</H4>
<P> To use the cosTransactions application <STRONG>participants</STRONG> must be implemented.
There are two types of participants:
<P>
<UL>
<LI>
<A HREF="CosTransactions_Resource.html">CosTransactions_Resource</A> - operations used to commit or rollback resources.
</LI>
<LI>
<A HREF="CosTransactions_SubtransactionAwareResource.html">CosTransactions_SubtransactionAwareResource</A> -
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>
<A NAME="4.1.2"><!-- Empty --></A>
<H4>4.1.2 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:
<PRE>
#ifndef _OWNRESOURCEIMPL_IDL
#define _OWNRESOURCEIMPL_IDL
#include <CosTransactions.idl>
module ownResourceImpl {
interface ownInterface:CosTransactions::Resource {
void ownFunctions(in any NeededArguments)
raises(Systemexceptions,OwnExceptions);
};
};
#endif
</PRE>
<P> Run the IDL compiler on this file by calling the <CODE>ic:gen/1</CODE> function.
This will produce the API named <CODE>ownResourceImpl_ownInterface.erl</CODE>.
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 <CODE>ownResourceImpl_ownInterface_impl.erl</CODE>.
<A NAME="4.1.3"><!-- Empty --></A>
<H4>4.1.3 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>
<CODE>prepare/1</CODE> - this operation is invoked on the Resource to begin the two-phase commit protocol.
</LI>
<LI>
<CODE>rollback/1</CODE> - this operation instructs the Resource to rollback all changes made as a part of the transaction.
</LI>
<LI>
<CODE>commit/1</CODE> - this operation instructs the Resource to commit all changes made as a part of the transaction.
</LI>
<LI>
<CODE>commit_one_phase/1</CODE> - 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>
<CODE>forget/1</CODE> - this operation informs the Resource that it is safe to forget any
<A HREF="part_term.html#Heuristic decisions">Heuristic decisions</A> and the knowledge of the transaction.
</LI>
<LI>
<CODE>ownFunctions</CODE> - 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>
<CODE>commit_subtransaction/2</CODE> - if the <CODE>SubtransactionAwareResource</CODE> have been registered
with a transactions using the operation <CODE>CosTransactions_Coordinator:register_subtran_aware/2</CODE> it will
be notified when the transaction has
committed.
</LI>
<LI>
<CODE>rollback_subtransaction/1</CODE> - if the <CODE>SubtransactionAwareResource</CODE> have been registered
with a transactions using the operation <CODE>CosTransactions_Coordinator:register_subtran_aware/2</CODE>
it will be notified when the transaction has
rolled back.
</LI>
</UL>
<P>
<TABLE CELLPADDING=4>
<TR>
<TD VALIGN=TOP><IMG ALT="Note!" SRC="note.gif"></TD>
<TD>
<P>
The results of a commited subtransaction are reltive to the completion of its ancestor transactions,
that is, these results can be undone if any ancestor transaction is rolled back.
</TD>
</TR>
</TABLE>
<A NAME="4.1.4"><!-- Empty --></A>
<H4>4.1.4 Particapant 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.
<A NAME="4.1.4.1"><!-- Empty --></A>
<H5>4.1.4.1 prepare</H5>
<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 <A HREF="CosTransactions_Resource.html">Heuristic Exception</A> and wait
until the <CODE>forget</CODE> 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>
<P>
<TABLE CELLPADDING=4>
<TR>
<TD VALIGN=TOP><IMG ALT="Note!" SRC="note.gif"></TD>
<TD>
<P> Before replying to the prepare operation, the Resource must record the prepare state, the reference of its
superior <A HREF="CosTransactions_RecoveryCoordinator.html">RecoveryCoordinator</A> in stable storage.
The RecoveryCoordinator is obtained when registering as a participant in a transaction.
</TD>
</TR>
</TABLE>
<A NAME="4.1.4.2"><!-- Empty --></A>
<H5>4.1.4.2 rollback</H5>
<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.
<A NAME="4.1.4.3"><!-- Empty --></A>
<H5>4.1.4.3 commit</H5>
<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.
<A NAME="4.1.4.4"><!-- Empty --></A>
<H5>4.1.4.4 commit_one_phase</H5>
<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.
<A NAME="4.1.4.5"><!-- Empty --></A>
<H5>4.1.4.5 forget</H5>
<P> If the Resource raised a Heuristic Exception to <CODE>commit</CODE>, <CODE>rollback</CODE> or <CODE>commit_one_phase</CODE> this operation
will be performed. The Resource can forget all knowledge of the transaction and terminate.
<A NAME="4.1.4.6"><!-- Empty --></A>
<H5>4.1.4.6 commit_subtransaction</H5>
<P> If the <CODE>SubtransactionAwareResource</CODE> have been registered with a <STRONG>subtransaction</STRONG>
using the operation <CODE>CosTransactions_Coordinator:register_subtran_aware/2</CODE>
it will be notified when the transaction has committed. The Resource may raise the exception
<CODE>'TRANSACTION_ROLLEDBACK'</CODE>.
<P>
<TABLE CELLPADDING=4>
<TR>
<TD VALIGN=TOP><IMG ALT="Note!" SRC="note.gif"></TD>
<TD>
<P> The result of a commited subtransaction is reltive to the completion of its ancestor
transactions, that is, these results can be undone if any ancestor transaction is rolled back.
</TD>
</TR>
</TABLE>
<A NAME="4.1.4.7"><!-- Empty --></A>
<H5>4.1.4.7 rollback_subtransaction</H5>
<P> If the <CODE>SubtransactionAwareResource</CODE> have been registered with a <STRONG>subtransaction</STRONG>
using the operation <CODE>CosTransactions_Coordinator:register_subtran_aware/2</CODE>
it will be notified when the subtransaction has rolled back.
<A NAME="4.1.5"><!-- Empty --></A>
<H4>4.1.5 How to Run Everything</H4>
<P> Below is a short transcript on how to run cosTransactions.
<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 > 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>
<P>
<TABLE CELLPADDING=4>
<TR>
<TD VALIGN=TOP><IMG ALT="Note!" SRC="note.gif"></TD>
<TD>
<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.
</TD>
</TR>
</TABLE>
<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>
<CENTER>
<HR>
<SMALL>
Copyright © 1991-2006
<A HREF="http://www.erlang.se">Ericsson AB</A><BR>
</SMALL>
</CENTER>
</BODY>
</HTML>
|