KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > jts > CosTransactions > XATerminatorImpl


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 /*
25  * Copyright 2004-2005 Sun Microsystems, Inc. All rights reserved.
26  * Use is subject to license terms.
27  */

28  
29 package com.sun.jts.CosTransactions;
30
31 import javax.transaction.xa.Xid JavaDoc;
32 import javax.transaction.xa.XAException JavaDoc;
33 import javax.transaction.xa.XAResource JavaDoc;
34
35 import javax.resource.spi.XATerminator JavaDoc;
36
37 import org.omg.CosTransactions.Vote;
38 import org.omg.CosTransactions.HeuristicMixed;
39
40 /**
41  * This is used for transaction completion and crash recovery flows.
42  *
43  * @version 1.0
44  * @author Ram Jeyaraman
45  */

46 public class XATerminatorImpl implements XATerminator JavaDoc {
47
48     private static void check(Xid JavaDoc xid) throws XAException JavaDoc {
49         // check if xid is valid
50
if (xid == null || xid.getFormatId() == 0 ||
51                 xid.getBranchQualifier() == null ||
52                 xid.getGlobalTransactionId() == null) {
53             throw new XAException JavaDoc(XAException.XAER_NOTA);
54         }
55     }
56     
57     /**
58      * Commits the global transaction specified by xid.
59      *
60      * @param xid A global transaction identifier
61      *
62      * @param onePhase If true, the resource manager should use a one-phase
63      * commit protocol to commit the work done on behalf of xid.
64      *
65      * @exception XAException An error has occurred. Possible XAExceptions
66      * are XA_HEURHAZ, XA_HEURCOM, XA_HEURRB, XA_HEURMIX, XAER_RMERR,
67      * XAER_RMFAIL, XAER_NOTA, XAER_INVAL, or XAER_PROTO.
68      *
69      * <P>If the resource manager did not commit the transaction and the
70      * parameter onePhase is set to true, the resource manager may throw
71      * one of the XA_RB* exceptions. Upon return, the resource manager has
72      * rolled back the branch's work and has released all held resources.
73      */

74     public void commit(Xid JavaDoc xid, boolean onePhase) throws XAException JavaDoc {
75         
76         check(xid); // check if xid is valid
77

78         GlobalTID tid = new GlobalTID(xid);
79
80         // check for concurrent activity
81
if (RecoveryManager.readAndUpdateTxMap(tid) == false) {
82             throw new XAException JavaDoc(XAException.XAER_PROTO);
83         }
84         
85         boolean exceptionFlag = false;
86         int errorCode = XAException.XAER_PROTO;
87         try {
88             // First of all make sure it has been recovered if necessary
89
RecoveryManager.waitForRecovery();
90     
91             // Look up the Coordinator for the transaction.
92
TopCoordinator coord = (TopCoordinator)
93                                     RecoveryManager.getCoordinator(tid);
94         
95             if (coord == null) { // error to receive commit more than once
96
errorCode = XAException.XAER_PROTO;
97                 throw new XAException JavaDoc(errorCode);
98             }
99             
100             // If there is a Coordinator, lock it for the duration of this
101
// operation. Tell the Coordinator to commit.
102
synchronized (coord) {
103                 if (onePhase) {
104                     coord.beforeCompletion();
105                     if (coord.getParticipantCount() == 1) {
106                         coord.commitOnePhase();
107                     } else {
108                         Vote vote = Vote.VoteRollback;
109                         try {
110                             vote = coord.prepare();
111                         } catch (HeuristicMixed exc) {
112                             errorCode = XAException.XA_HEURHAZ;
113                             throw new XAException JavaDoc(errorCode);
114                         }
115                         if (vote == Vote.VoteCommit) {
116                             coord.commit();
117                         } else if (vote == Vote.VoteRollback) {
118                             coord.rollback(true);
119                         }
120                     }
121                 } else {
122                     coord.commit();
123                 }
124             }
125         } catch (Throwable JavaDoc exc) {
126             exceptionFlag = true;
127             XAException JavaDoc xaExc = new XAException JavaDoc(errorCode);
128             xaExc.initCause(exc);
129             throw xaExc;
130         } finally {
131             Thread JavaDoc thread = RecoveryManager.removeFromTxMap(tid);
132             if (thread == null || (thread != Thread.currentThread())) { // error
133
if (!exceptionFlag) {
134                     throw new XAException JavaDoc(XAException.XAER_RMERR);
135                 }
136             }
137         }
138     }
139
140     /**
141      * Tells the resource manager to forget about a heuristically
142      * completed transaction branch.
143      *
144      * @param xid A global transaction identifier.
145      *
146      * @exception XAException An error has occurred. Possible exception
147      * values are XAER_RMERR, XAER_RMFAIL, XAER_NOTA, XAER_INVAL, or
148      * XAER_PROTO.
149      */

150     public void forget(Xid JavaDoc xid) throws XAException JavaDoc {}
151     
152     /**
153      * Ask the resource manager to prepare for a transaction commit
154      * of the transaction specified in xid.
155      *
156      * @param xid A global transaction identifier.
157      *
158      * @exception XAException An error has occurred. Possible exception
159      * values are: XA_RB*, XAER_RMERR, XAER_RMFAIL, XAER_NOTA, XAER_INVAL,
160      * or XAER_PROTO.
161      *
162      * @return A value indicating the resource manager's vote on the
163      * outcome of the transaction. The possible values are: XA_RDONLY
164      * or XA_OK. These constants are defined in
165      * <code> javax.transaction.xa.XATerminator</code> interface.
166      * If the resource manager wants to roll back the
167      * transaction, it should do so by raising an appropriate XAException
168      * in the prepare method.
169      */

170     public int prepare(Xid JavaDoc xid) throws XAException JavaDoc {
171         
172         check(xid); // check if xid is valid
173

174         GlobalTID tid = new GlobalTID(xid);
175
176         // check for concurrent activity
177
if (RecoveryManager.readAndUpdateTxMap(tid) == false) {
178             throw new XAException JavaDoc(XAException.XAER_PROTO);
179         }
180         
181         boolean exceptionFlag = false;
182         int errorCode = XAException.XAER_PROTO;
183         try {
184             // First of all make sure it has been recovered if necessary
185
RecoveryManager.waitForRecovery();
186     
187             // Look up the Coordinator for the transaction.
188
TopCoordinator coord = (TopCoordinator)
189                                     RecoveryManager.getCoordinator(tid);
190         
191             if (coord == null) { // error to receive prepare more than once
192
errorCode = XAException.XAER_PROTO;
193                 throw new XAException JavaDoc(errorCode);
194             }
195             
196             // If there is a Coordinator, lock it for the duration of this
197
// operation. Tell the Coordinator to commit.
198
synchronized (coord) {
199                 coord.beforeCompletion();
200                 Vote vote = coord.prepare();
201                 if (vote == Vote.VoteRollback) {
202                     errorCode = XAException.XA_RBROLLBACK;
203                 } else if (vote == Vote.VoteCommit) {
204                     return XAResource.XA_OK;
205                 } else if (vote == Vote.VoteReadOnly) {
206                     return XAResource.XA_RDONLY;
207                 }
208                 throw new XAException JavaDoc(errorCode);
209             }
210         } catch (Throwable JavaDoc exc) {
211             exceptionFlag = true;
212             XAException JavaDoc xaExc = new XAException JavaDoc(errorCode);
213             xaExc.initCause(exc);
214             throw xaExc;
215         } finally {
216             Thread JavaDoc thread = RecoveryManager.removeFromTxMap(tid);
217             if (thread == null || (thread != Thread.currentThread())) { // error
218
if (!exceptionFlag) {
219                     throw new XAException JavaDoc(XAException.XAER_RMERR);
220                 }
221             }
222         }
223     }
224
225     /**
226      * Obtains a list of prepared transaction branches from a resource
227      * manager. The transaction manager calls this method during recovery
228      * to obtain the list of transaction branches that are currently in
229      * prepared or heuristically completed states.
230      *
231      * @param flag One of TMSTARTRSCAN, TMENDRSCAN, TMNOFLAGS. TMNOFLAGS
232      * must be used when no other flags are set in the parameter. These
233      * constants are defined in <code>javax.transaction.xa.XATerminator</code>
234      * interface.
235      *
236      * @exception XAException An error has occurred. Possible values are
237      * XAER_RMERR, XAER_RMFAIL, XAER_INVAL, and XAER_PROTO.
238      *
239      * @return The resource manager returns zero or more XIDs of the
240      * transaction branches that are currently in a prepared or
241      * heuristically completed state. If an error occurs during the
242      * operation, the resource manager should throw the appropriate
243      * XAException.
244      */

245     public Xid JavaDoc[] recover(int flag) throws XAException JavaDoc {
246         
247         // wait for recovery to be completed.
248
RecoveryManager.waitForResync();
249         
250         return (Xid JavaDoc[]) TimeoutManager.getInDoubtXids();
251     }
252
253     /**
254      * Informs the resource manager to roll back work done on behalf
255      * of a transaction branch.
256      *
257      * @param xid A global transaction identifier.
258      *
259      * @exception XAException An error has occurred. Possible XAExceptions are
260      * XA_HEURHAZ, XA_HEURCOM, XA_HEURRB, XA_HEURMIX, XAER_RMERR, XAER_RMFAIL,
261      * XAER_NOTA, XAER_INVAL, or XAER_PROTO.
262      *
263      * <p>If the transaction branch is already marked rollback-only the
264      * resource manager may throw one of the XA_RB* exceptions. Upon return,
265      * the resource manager has rolled back the branch's work and has released
266      * all held resources.
267      */

268     public void rollback(Xid JavaDoc xid) throws XAException JavaDoc {
269         
270         check(xid); // check if xid is valid
271

272         GlobalTID tid = new GlobalTID(xid);
273
274         // check for concurrent activity
275
if (RecoveryManager.readAndUpdateTxMap(tid) == false) {
276             throw new XAException JavaDoc(XAException.XAER_PROTO);
277         }
278         
279         boolean exceptionFlag = false;
280         int errorCode = XAException.XAER_PROTO;
281         try {
282             // First of all make sure it has been recovered if necessary
283
RecoveryManager.waitForRecovery();
284     
285             // Look up the Coordinator for the transaction.
286
TopCoordinator coord = (TopCoordinator)
287                                     RecoveryManager.getCoordinator(tid);
288         
289             if (coord == null) { // error to receive rollback more than once
290
errorCode = XAException.XAER_PROTO;
291                 throw new XAException JavaDoc(errorCode);
292             }
293             
294             // If there is a Coordinator, lock it for the duration of this
295
// operation. Tell the Coordinator to commit.
296
synchronized (coord) {
297                 coord.rollback(true);
298             }
299         } catch (Throwable JavaDoc exc) {
300             exceptionFlag = true;
301             XAException JavaDoc xaExc = new XAException JavaDoc(errorCode);
302             xaExc.initCause(exc);
303             throw xaExc;
304         } finally {
305             Thread JavaDoc thread = RecoveryManager.removeFromTxMap(tid);
306             if (thread == null || (thread != Thread.currentThread())) { // error
307
if (!exceptionFlag) {
308                     throw new XAException JavaDoc(XAException.XAER_RMERR);
309                 }
310             }
311         }
312     }
313 }
314
315
316
Popular Tags