KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jacorb > transaction > CoordinatorImpl


1 package org.jacorb.transaction;
2
3 /*
4  * JacORB transaction service - a free TS for JacORB
5  *
6  * Copyright (C) 1999-2004 LogicLand group Alex Sinishin.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the Free
20  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */

22
23 import org.omg.CosTransactions.*;
24 import org.omg.CosTransactions.Terminator;
25
26 import java.util.*;
27
28
29 /**
30  * Instances of this class represent transactions. A single instance
31  * is used for implementing the Coordinator, Terminator and Control
32  * CORBA objects.
33  *
34  * @author Nicolas Noffke
35  * @author Vladimir Mencl
36  * @version $Id: CoordinatorImpl.java,v 1.8 2004/05/06 12:40:01 nicolas Exp $
37  *
38  * Changes made by Vladimir Mencl <vladimir.mencl@mff.cuni.cz> (2002/07/15)
39  *
40  * * handle TRANSACTION_ROLLEDBACK raised by commit_one_phase()
41  * called from commit()
42  *
43  */

44
45 public class CoordinatorImpl
46     implements Sleeper, CoordinatorOperations,
47                ControlOperations, TerminatorOperations
48 {
49     private Terminator JavaDoc term_ref;
50     private TerminatorPOATie term_skel;
51     private Coordinator coord_ref;
52     private CoordinatorPOATie coord_skel;
53     private Control contr_ref;
54     private ControlPOATie contr_skel;
55
56     private int transaction_id;
57     private int hash_code;
58
59     private int status;
60     private String JavaDoc stat_semaphore;
61
62     private Vector resources;
63     private Vector votes;
64     private Vector syncs;
65
66     private org.omg.PortableServer.POA JavaDoc poa;
67
68     CoordinatorImpl(org.omg.PortableServer.POA JavaDoc _poa, int _trans_id,
69                     int _hash_code, int time)
70     {
71         transaction_id = _trans_id;
72         hash_code = _hash_code;
73         poa = _poa;
74         stat_semaphore = new String JavaDoc("sss");
75         resources = new Vector();
76         syncs = new Vector();
77         votes = new Vector();
78         try {
79             coord_skel = new CoordinatorPOATie(this);
80             coord_ref = CoordinatorHelper.narrow(poa.servant_to_reference(coord_skel));
81             term_skel = new TerminatorPOATie(this);
82             term_ref = TerminatorHelper.narrow(poa.servant_to_reference(term_skel));
83
84             contr_skel = new ControlPOATie(this);
85             contr_ref = ControlHelper.narrow(poa.servant_to_reference(contr_skel));
86
87         } catch (org.omg.PortableServer.POAPackage.ServantNotActive JavaDoc esn){
88             throw new org.omg.CORBA.INTERNAL JavaDoc();
89         } catch (org.omg.PortableServer.POAPackage.WrongPolicy JavaDoc ew){
90             throw new org.omg.CORBA.INTERNAL JavaDoc();
91         }
92         status = Status._StatusActive;
93         if (time != 0){
94             TransactionService.get_timer().add_channel(this, time);
95         }
96     }
97
98     private void destroy(){
99         try {
100             byte[] oid = poa.reference_to_id(term_ref);
101             poa.deactivate_object(oid);
102             term_ref._release();
103
104             oid = poa.reference_to_id(coord_ref);
105             poa.deactivate_object(oid);
106             coord_ref._release();
107
108             oid = poa.reference_to_id(contr_ref);
109             poa.deactivate_object(oid);
110             contr_ref._release();
111
112         } catch (org.omg.PortableServer.POAPackage.ObjectNotActive JavaDoc esn){
113             throw new org.omg.CORBA.INTERNAL JavaDoc();
114         } catch (org.omg.PortableServer.POAPackage.WrongPolicy JavaDoc ew){
115             throw new org.omg.CORBA.INTERNAL JavaDoc();
116         } catch (org.omg.PortableServer.POAPackage.WrongAdapter JavaDoc ew){
117             throw new org.omg.CORBA.INTERNAL JavaDoc();
118         }
119         TransactionService.release_coordinator(hash_code);
120     }
121
122     private boolean move_to_state(int new_status){
123         synchronized(stat_semaphore){
124             switch(status){
125             case Status._StatusActive:
126                 switch(new_status){
127                 case Status._StatusMarkedRollback:
128                 case Status._StatusPreparing:
129                 case Status._StatusRollingBack:
130                     status = new_status;
131                     return true;
132                 default:
133                     return false;
134                 }
135             case Status._StatusMarkedRollback:
136                 switch(new_status){
137                 case Status._StatusRollingBack:
138                     status = new_status;
139                     return true;
140                 default:
141                     return false;
142                 }
143             case Status._StatusPrepared:
144                 switch(new_status){
145                 case Status._StatusCommitting:
146                     status = new_status;
147                     return true;
148                 default:
149                     return false;
150                 }
151             case Status._StatusCommitted:
152                 switch(new_status){
153                 case Status._StatusNoTransaction:
154                     status = new_status;
155                     return true;
156                 default:
157                     return false;
158                 }
159             case Status._StatusRolledBack:
160                 switch(new_status){
161                 case Status._StatusNoTransaction:
162                     status = new_status;
163                     return true;
164                 default:
165                     return false;
166                 }
167             case Status._StatusUnknown:
168                 throw new org.omg.CORBA.INTERNAL JavaDoc();
169             case Status._StatusNoTransaction:
170                 throw new org.omg.CORBA.INTERNAL JavaDoc();
171             case Status._StatusPreparing:
172                 switch(new_status){
173                 case Status._StatusRollingBack:
174                 case Status._StatusPrepared:
175                     status = new_status;
176                     return true;
177                 default:
178                     return false;
179                 }
180             case Status._StatusCommitting:
181                 switch(new_status){
182                 case Status._StatusCommitted:
183                     status = new_status;
184                     return true;
185                 default:
186                     return false;
187                 }
188             case Status._StatusRollingBack:
189                 switch(new_status){
190                 case Status._StatusRolledBack:
191                     status = new_status;
192                     return true;
193                 default:
194                     return false;
195                 }
196             default:
197                 throw new org.omg.CORBA.INTERNAL JavaDoc();
198             }
199         }
200     }
201
202     public void wakeup(){
203         TransactionService.get_timer().kill_channel(this);
204         if (move_to_state(Status._StatusRollingBack)){
205             rolling_to_back();
206         }
207     }
208
209     int _get_transaction_id(){
210         return transaction_id;
211     }
212
213     Control _get_control(){
214         return contr_ref;
215     }
216
217     public Status get_status(){
218         return Status.from_int(status);
219     }
220
221     public Status get_parent_status(){
222         throw new org.omg.CORBA.NO_IMPLEMENT JavaDoc();
223     }
224
225     public Status get_top_level_status(){
226         return Status.from_int(status);
227     }
228
229     public boolean is_same_transaction(Coordinator tc){
230         return (hash_code == tc.hash_transaction());
231     }
232
233     public boolean is_related_transaction(Coordinator tc){
234         throw new org.omg.CORBA.NO_IMPLEMENT JavaDoc();
235     }
236
237     public boolean is_ancestor_transaction(Coordinator tc){
238         throw new org.omg.CORBA.NO_IMPLEMENT JavaDoc();
239     }
240
241     public boolean is_descendant_transaction(Coordinator tc){
242         throw new org.omg.CORBA.NO_IMPLEMENT JavaDoc();
243     }
244
245     public boolean is_top_level_transaction(){
246         return true;
247     }
248
249     public int hash_transaction(){
250         return hash_code;
251     }
252
253     public int hash_top_level_tran(){
254         throw new org.omg.CORBA.NO_IMPLEMENT JavaDoc();
255     }
256
257     public RecoveryCoordinator register_resource(Resource r) throws Inactive{
258         synchronized(stat_semaphore){
259             if (status == Status._StatusMarkedRollback){
260                 throw new org.omg.CORBA.TRANSACTION_ROLLEDBACK JavaDoc();
261             }
262             if (status != Status._StatusActive){
263                 throw new Inactive();
264             }
265             resources.addElement(r);
266             votes.addElement(null);
267         }
268         return null;
269     }
270
271     public void register_synchronization(Synchronization sync)
272         throws Inactive, SynchronizationUnavailable{
273         synchronized(stat_semaphore){
274             if (status == Status._StatusMarkedRollback){
275                 throw new org.omg.CORBA.TRANSACTION_ROLLEDBACK JavaDoc();
276             }
277             if (status != Status._StatusActive){
278                 throw new Inactive();
279             }
280             syncs.addElement(sync);
281         }
282     }
283
284     public void register_subtran_aware(SubtransactionAwareResource r)
285         throws Inactive, NotSubtransaction{
286         throw new org.omg.CORBA.NO_IMPLEMENT JavaDoc();
287     }
288
289     public void rollback_only() throws Inactive{
290         if (!move_to_state(Status._StatusMarkedRollback)){
291             throw new Inactive();
292         }
293     }
294
295     public String JavaDoc get_transaction_name(){
296         return "Transaction_" + transaction_id;
297     }
298
299     public Control create_subtransaction()
300         throws SubtransactionsUnavailable, Inactive{
301         throw new org.omg.CORBA.NO_IMPLEMENT JavaDoc();
302     }
303
304     public PropagationContext get_txcontext() throws Unavailable{
305         throw new org.omg.CORBA.NO_IMPLEMENT JavaDoc();
306     }
307
308     public Terminator JavaDoc get_terminator() throws Unavailable{
309         if (status == Status._StatusNoTransaction){
310             throw new Unavailable();
311         }
312         return term_ref;
313     }
314
315     public Coordinator get_coordinator() throws Unavailable{
316         if (status == Status._StatusNoTransaction){
317             throw new Unavailable();
318         }
319         return coord_ref;
320     }
321
322     private void forget(){
323         resources.removeAllElements();
324         votes.removeAllElements();
325         syncs.removeAllElements();
326     }
327
328     public void commit(boolean report_heuristics) throws HeuristicMixed,
329         HeuristicHazard{
330         if (!move_to_state(Status._StatusPreparing)){
331             if (move_to_state(Status._StatusRollingBack)){
332                 TransactionService.get_timer().kill_channel(this);
333                 rolling_to_back();
334                 throw new org.omg.CORBA.TRANSACTION_ROLLEDBACK JavaDoc();
335             }
336             throw new org.omg.CORBA.INTERNAL JavaDoc();
337         }
338
339         TransactionService.get_timer().kill_channel(this);
340
341         for (int i = 0;i < syncs.size();i++){
342             Synchronization sync = (Synchronization)syncs.elementAt(i);
343             sync.before_completion();
344         }
345
346         if (resources.size() == 1){
347
348             Resource r = (Resource)resources.elementAt(0);
349             try {
350                 r.commit_one_phase();
351         } catch(org.omg.CORBA.TRANSACTION_ROLLEDBACK JavaDoc tr) {
352               // the only one resource requested a rollback
353
votes.setElementAt(Vote.VoteRollback,0);
354           rollback();
355           throw new org.omg.CORBA.TRANSACTION_ROLLEDBACK JavaDoc();
356             } catch(HeuristicHazard hh) {
357                 throw new org.omg.CORBA.NO_IMPLEMENT JavaDoc();
358             }
359         votes.setElementAt(Vote.VoteCommit,0);
360
361             if (!move_to_state(Status._StatusPrepared)){
362                 throw new org.omg.CORBA.INTERNAL JavaDoc();
363             }
364             if (!move_to_state(Status._StatusCommitting)){
365                 throw new org.omg.CORBA.INTERNAL JavaDoc();
366             }
367         } else {
368             for (int i = 0;i < resources.size();i++){
369                 Resource r = (Resource)resources.elementAt(i);
370                 try {
371                     Vote v = r.prepare();
372                     votes.setElementAt(v, i);
373                     if (v.value() == Vote._VoteRollback){
374
375                         rollback();
376                         throw new org.omg.CORBA.TRANSACTION_ROLLEDBACK JavaDoc();
377
378                     }
379                 } catch(HeuristicHazard hh) {
380                     throw new org.omg.CORBA.NO_IMPLEMENT JavaDoc();
381                 } catch(HeuristicMixed hm) {
382                     throw new org.omg.CORBA.NO_IMPLEMENT JavaDoc();
383                 }
384             }
385
386             if (!move_to_state(Status._StatusPrepared)){
387                 throw new org.omg.CORBA.INTERNAL JavaDoc();
388             }
389             if (!move_to_state(Status._StatusCommitting)){
390                 throw new org.omg.CORBA.INTERNAL JavaDoc();
391             }
392
393             for (int i = 0;i < resources.size();i++){
394                 Resource r = (Resource)resources.elementAt(i);
395                 Vote v = (Vote)votes.elementAt(i);
396                 
397                 try {
398                     if (v == null){
399                         throw new org.omg.CORBA.INTERNAL JavaDoc();
400                     } else {
401                         if (v.value() == Vote._VoteCommit){
402                             r.commit();
403                         }
404                     }
405                 } catch(NotPrepared np) {
406                     throw new org.omg.CORBA.NO_IMPLEMENT JavaDoc();
407                 } catch(HeuristicRollback hr) {
408                     throw new org.omg.CORBA.NO_IMPLEMENT JavaDoc();
409                 } catch(HeuristicHazard hh) {
410                     throw new org.omg.CORBA.NO_IMPLEMENT JavaDoc();
411                 } catch(HeuristicMixed hm) {
412                     throw new org.omg.CORBA.NO_IMPLEMENT JavaDoc();
413                 }
414             }
415         }
416
417         if (!move_to_state(Status._StatusCommitted)){
418             throw new org.omg.CORBA.INTERNAL JavaDoc();
419         }
420
421         forget();
422
423         if (!move_to_state(Status._StatusNoTransaction)){
424             throw new org.omg.CORBA.INTERNAL JavaDoc();
425         }
426         destroy();
427     }
428
429     private void rolling_to_back(){
430         for (int i = 0;i < resources.size();i++){
431             Resource r = (Resource)resources.elementAt(i);
432             Vote v = (Vote)votes.elementAt(i);
433             try {
434                 if (v == null){
435                     r.rollback();
436                 } else {
437                     if (v.value() == Vote._VoteCommit){
438                         r.rollback();
439                     }
440                 }
441             } catch(HeuristicCommit hc) {
442                 throw new org.omg.CORBA.NO_IMPLEMENT JavaDoc();
443             } catch(HeuristicMixed hm) {
444                 throw new org.omg.CORBA.NO_IMPLEMENT JavaDoc();
445             } catch(HeuristicHazard hh) {
446                 throw new org.omg.CORBA.NO_IMPLEMENT JavaDoc();
447             }
448         }
449
450         if (!move_to_state(Status._StatusRolledBack)){
451             throw new org.omg.CORBA.INTERNAL JavaDoc();
452         }
453
454         forget();
455
456         if (!move_to_state(Status._StatusNoTransaction)){
457             throw new org.omg.CORBA.INTERNAL JavaDoc();
458         }
459         destroy();
460     }
461
462     public void rollback(){
463         if (!move_to_state(Status._StatusRollingBack)){
464             throw new org.omg.CORBA.TRANSACTION_REQUIRED JavaDoc();
465         }
466         TransactionService.get_timer().kill_channel(this);
467         rolling_to_back();
468     }
469 }
470
471
472
473
474
475
476
477
478
479
480
481
482
483
Popular Tags