KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ozoneDB > xa > OzoneXAResource


1 // You can redistribute this software and/or modify it under the terms of
2
// the Ozone Library License version 1 published by ozone-db.org.
3
//
4
// The original code and portions created by SMB are
5
// Copyright (C) 1997-@year@ by SMB GmbH. All rights reserved.
6
//
7
// $Id: OzoneXAResource.java,v 1.3 2002/09/18 06:54:18 per_nyfelt Exp $
8

9 package org.ozoneDB.xa;
10
11 import org.ozoneDB.DxLib.*;
12 import org.ozoneDB.ExternalDatabase;
13 import org.ozoneDB.TransactionException;
14
15 import javax.transaction.Status JavaDoc;
16 import javax.transaction.xa.*;
17 import java.io.PrintStream JavaDoc;
18
19
20 /**
21  * This is the XA adapter (XAResource) for an ozone database connection. It is
22  * created using the getXAResource method of an ExternalDatabase. It allows an
23  * TransactionManager to control transaction demarcation in an ozone database.
24  *
25  * @author <a HREF="http://www.softwarebuero.de/">SMB</a>
26  * @version $Revision: 1.3 $Date: 2002/09/18 06:54:18 $
27  */

28 public class OzoneXAResource implements XAResource {
29     
30     private ExternalDatabase db;
31     
32     private DxHashMap xids;
33     
34     private PrintStream JavaDoc log;
35     
36     
37     public OzoneXAResource( ExternalDatabase _db ) {
38         db = _db;
39         xids = new DxHashMap();
40         log = System.out;
41     }
42     
43     
44     public String JavaDoc toString() {
45         return "OzoneXAResource [" + db + "]";
46     }
47     
48     
49     protected void debug( String JavaDoc msg ) {
50         log.println( "OzoneXAResource: " + msg );
51     }
52     
53     
54     /**
55      * Start work on behalf of a transaction branch specified in xid. If TMJOIN
56      * is specified, the start is for joining a transaction previously seen by
57      * the resource manager. If TMRESUME is specified, the start is to resume a
58      * suspended transaction specified in the parameter xid. If neither TMJOIN
59      * nor TMRESUME is specified and the transaction specified by xid has
60      * previously been seen by the resource manager, the resource manager throws
61      * the XAException exception with XAER_DUPID error code.
62      */

63     public void start( Xid xid, int flags ) throws XAException {
64         debug( "start(): xid:" + xid.hashCode() + ", flags:" + flags );
65         
66         if (xid == null) {
67             throw new XAException( XAException.XAER_INVAL );
68         }
69         if (db == null) {
70             throw new XAException( XAException.XAER_OUTSIDE );
71         }
72         
73         try {
74             switch (flags) {
75             case TMNOFLAGS: {
76                 debug( "start(): TMNOFLAGS..." );
77                 XATransaction tx = new XATransaction( db );
78                 if (!xids.addForKey( tx, xid )) {
79                     throw new XAException( XAException.XAER_DUPID );
80                 }
81                 db.beginTX( tx );
82                 break;
83             }
84             case TMRESUME : {
85                 debug( "start(): TMRESUME..." );
86                 XATransaction tx = (XATransaction)xids.elementForKey( xid );
87                 if (tx == null) {
88                     throw new XAException( "Specified XID not found." );
89                 }
90                 db.joinTX( tx );
91                 break;
92             }
93             case TMJOIN : {
94                 debug( "start(): TMJOIN..." );
95                 throw new RuntimeException JavaDoc( "Not implemented yet." );
96             }
97             default: {
98                 debug( "start(): unknown flag..." );
99                 
100                 // No other flags are supported in start().
101
throw new XAException( XAException.XAER_INVAL );
102             }
103             }
104         }
105         catch (XAException e) {
106             throw e;
107         }
108         catch (Exception JavaDoc e) {
109             log.println( e );
110             throw new XAException( XAException.XAER_RMERR );
111         }
112     }
113     
114     
115     /**
116      * Ends the work performed on behalf of a transaction branch. The resource
117      * manager disassociates the XA resource from the transaction branch
118      * specified and let the transaction be completed.
119      *
120      * If TMSUSPEND is specified in flags, the transaction branch is temporarily
121      * suspended in incomplete state. The transaction context is in suspened
122      * state and must be resumed via start with TMRESUME specified.
123      *
124      *
125      * If TMFAIL is specified, the portion of work has failed. The resource
126      * manager may mark the transaction as rollback-only If TMSUCCESS is
127      * specified, the portion of work has completed successfully.
128      */

129     public void end( Xid xid, int flags ) throws XAException {
130         debug( "end(): xid:" + xid.hashCode() + ", flags:" + flags );
131         
132         if (xid == null) {
133             throw new XAException( XAException.XAER_INVAL );
134         }
135         
136         try {
137             XATransaction tx = (XATransaction)xids.elementForKey( xid );
138             if (xid == null) {
139                 throw new XAException( XAException.XAER_NOTA );
140             }
141             
142             switch (flags) {
143             case TMSUCCESS: {
144                 debug( "end(): TMSUCCESS..." );
145                 db.leaveTX( tx );
146                 break;
147             }
148             case TMFAIL: {
149                 debug( "end(): TMFAIL..." );
150                 db.rollbackTX( tx );
151                 break;
152             }
153             case TMSUSPEND: {
154                 debug( "end(): TMSUSPEND..." );
155                 db.leaveTX( tx );
156                 break;
157             }
158             default: {
159                 debug( "end(): unknown flag..." );
160                 
161                 // No other flags are supported in end().
162
throw new XAException( XAException.XAER_INVAL );
163             }
164             }
165         }
166         catch (XAException e) {
167             throw e;
168         }
169         catch (Exception JavaDoc e) {
170             log.println( e );
171             throw new XAException( XAException.XAER_RMERR );
172         }
173     }
174     
175     
176     /**
177      * Ask the resource manager to prepare for a transaction commit of the
178      * transaction specified in xid.
179      */

180     public int prepare( Xid xid ) throws XAException {
181         debug( "prepare(): xid:" + xid.hashCode() );
182         
183         if (xid == null) {
184             throw new XAException( XAException.XAER_INVAL );
185         }
186         
187         try {
188             XATransaction tx = (XATransaction)xids.elementForKey( xid );
189             if (xid == null) {
190                 throw new XAException( XAException.XAER_NOTA );
191             }
192             db.prepareTX( tx );
193             return XA_OK;
194         }
195         catch (XAException e) {
196             throw e;
197         }
198         catch (TransactionException e) {
199             log.println( e );
200             throw new XAException( XAException.XA_RBROLLBACK );
201         }
202         catch (Exception JavaDoc e) {
203             log.println( e );
204             throw new XAException( XAException.XAER_RMERR );
205         }
206     }
207     
208     
209     /**
210      * Commit the global transaction specified by xid.
211      */

212     public void commit( Xid xid, boolean onePhase ) throws XAException {
213         debug( "commit(): xid:" + xid.hashCode() + ", onePhase:" + onePhase );
214         
215         if (xid == null) {
216             throw new XAException( XAException.XAER_INVAL );
217         }
218         
219         try {
220             XATransaction tx = (XATransaction)xids.elementForKey( xid );
221             if (xid == null) {
222                 throw new XAException( XAException.XAER_NOTA );
223             }
224             db.commitTX( tx, onePhase );
225         }
226         catch (XAException e) {
227             throw e;
228         }
229         catch (TransactionException e) {
230             log.println( e );
231             throw new XAException( XAException.XA_RBROLLBACK );
232         }
233         catch (Exception JavaDoc e) {
234             log.println( e );
235             throw new XAException( XAException.XAER_RMERR );
236         }
237     }
238     
239     
240     /**
241      * Inform the resource manager to roll back work done on behalf of a
242      * transaction branch.
243      */

244     public void rollback( Xid xid ) throws XAException {
245         debug( "rollback(): xid:" + xid.hashCode() );
246         
247         if (xid == null) {
248             throw new XAException( XAException.XAER_INVAL );
249         }
250         
251         try {
252             XATransaction tx = (XATransaction)xids.elementForKey( xid );
253             if (xid == null) {
254                 throw new XAException( XAException.XAER_NOTA );
255             }
256             db.rollbackTX( tx );
257         }
258         catch (XAException e) {
259             throw e;
260         }
261         catch (Exception JavaDoc e) {
262             log.println( e );
263             throw new XAException( XAException.XAER_RMERR );
264         }
265     }
266     
267     
268     /**
269      * Tell the resource manager to forget about a heuristically completed
270      * transaction branch.
271      */

272     public void forget( Xid xid ) throws XAException {
273         debug( "forget(): xid:" + xid.hashCode() );
274         
275         xids.removeForKey( xid );
276     }
277     
278     
279     /**
280      * Set the current transaction timeout value for this XAResource instance.
281      * Once set, this timeout value is effective until setTransactionTimeout is
282      * invoked again with a different value. To reset the timeout value to the
283      * default value used by the resource manager, set the value to zero. If the
284      * timeout operation is performed successfully, the method returns true;
285      * otherwise false. If a resource manager does not support transaction
286      * timeout value to be set explicitly, this method returns false.
287      */

288     public boolean setTransactionTimeout( int seconds ) throws XAException {
289         debug( "setTransactionTimeout(): seconds:" + seconds );
290         return false;
291     }
292     
293     
294     /**
295      * Obtain the current transaction timeout value set for this XAResource
296      * instance. If XAResource.setTransactionTimeout was not use prior to
297      * invoking this method, the return value is the default timeout set for the
298      * resource manager; otherwise, the value used in the previous
299      * setTransactionTimeout call is returned.
300      */

301     public int getTransactionTimeout() throws XAException {
302         debug( "getTransactionTimeout():" );
303         return -1;
304     }
305     
306     
307     /**
308      * This method is called to determine if the resource manager instance
309      * represented by the target object is the same as the resouce manager
310      * instance represented by the parameter xares.
311      */

312     public boolean isSameRM( XAResource xares ) throws XAException {
313         debug( "isSameRM(): xares:" + xares );
314         
315         if (xares != null && xares instanceof OzoneXAResource) {
316             return db == ((OzoneXAResource)xares).db;
317         } else {
318             return false;
319         }
320     }
321     
322     
323     /**
324      * Obtain a list of prepared transaction branches from a resource manager.
325      * The transaction manager calls this method during recovery to obtain the
326      * list of transaction branches that are currently in prepared or
327      * heuristically completed states.
328      */

329     public Xid[] recover( int flag ) throws XAException {
330         debug( "recover(): flags:" + flag );
331         
332         try {
333             DxArrayBag result = new DxArrayBag();
334             DxIterator it = xids.iterator();
335             while (it.next() != null) {
336                 XATransaction tx = (XATransaction)it.object();
337                 if (db.getStatusTX( tx ) == Status.STATUS_PREPARED) {
338                     result.add( tx );
339                 }
340             }
341             
342             return (Xid[])result.toArray();
343         }
344         catch (Exception JavaDoc e) {
345             throw new XAException( e.toString() );
346         }
347     }
348     
349 }
350
Popular Tags