KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jonas > jdbc > XAResourceImpl


1  /*
2  * JOnAS: Java(TM) Open Application Server
3  * Copyright (C) 1999 Bull S.A.
4  * Contact: jonas-team@objectweb.org
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19  * USA
20  *
21  * Initial developer(s): Eric HARDESTY
22  * --------------------------------------------------------------------------
23  * $Id: XAResourceImpl.java,v 1.9 2005/04/28 08:43:24 benoitf Exp $
24  * --------------------------------------------------------------------------
25  */

26 package org.objectweb.jonas.jdbc;
27
28 import java.sql.SQLException JavaDoc;
29
30 import javax.resource.spi.ConnectionEvent JavaDoc;
31 import javax.transaction.xa.XAException JavaDoc;
32 import javax.transaction.xa.XAResource JavaDoc;
33 import javax.transaction.xa.Xid JavaDoc;
34
35 import org.objectweb.util.monolog.api.BasicLevel;
36
37 /**
38  * This is an implementation of XAResource used for transaction mgmt
39  * with a JDBC driver. The standard JDBC drivers don't support real
40  * XA, so the prepare will just return OK and work will be done in the
41  * commit/rollback.
42  */

43 public class XAResourceImpl implements XAResource JavaDoc {
44
45     // Current Xid
46
private Xid JavaDoc currentXid = null;
47
48     // Is a xa transaction started ?
49
boolean started = false;
50     boolean ended = true;
51
52     protected ManagedConnectionImpl mc = null;
53     private XAResource JavaDoc xares = null;
54
55     /**
56      * XAResourceImpl constructor
57      * @param mc ManagedConnectionImpl used with this object
58      * @param xares XAResource from DB if supported
59      */

60     public XAResourceImpl(ManagedConnectionImpl mc, XAResource JavaDoc xares) {
61         this.mc = mc;
62         this.xares = xares;
63         if (mc.trace.isLoggable(BasicLevel.DEBUG)) {
64             mc.trace.log(BasicLevel.DEBUG, "" + mc + "," + xares);
65         }
66     }
67
68     /**
69      * Commit the global transaction specified by xid.
70      */

71     public void commit(Xid JavaDoc xid, boolean onePhase) throws XAException JavaDoc {
72         if (mc.trace.isLoggable(BasicLevel.DEBUG)) {
73             mc.trace.log(BasicLevel.DEBUG, "" + xid + "," + onePhase);
74         }
75
76         // Commit the transaction
77
try {
78             if (xares != null) {
79                 xares.commit(xid, onePhase);
80                 if (xid.equals(currentXid)) {
81                     started = false;
82                 }
83             } else {
84                 // Make sure that this call is for the XID
85
if (currentXid == null || !currentXid.equals(xid) || !started) {
86                     mc.trace.log(BasicLevel.ERROR, "passed xid(" + xid
87                                                    + "),current Xid("
88                                                    + currentXid
89                                                    + "),started(" + started + ")");
90                     throw new XAException JavaDoc("Commit: Must call correct XAResource for its started XID");
91                 }
92                 mc.connection.commit();
93                 started = false;
94             }
95         } catch (XAException JavaDoc xe) {
96             mc.trace.log(BasicLevel.ERROR, xe.getMessage());
97             throw xe;
98         } catch (SQLException JavaDoc e) {
99             mc.trace.log(BasicLevel.ERROR, e.getMessage());
100             try {
101                 mc.signalEvent(ConnectionEvent.CONNECTION_ERROR_OCCURRED, null, e);
102             } catch (Exception JavaDoc ex) {}
103             throw new XAException JavaDoc("Error on commit");
104         }
105
106         try {
107             if (!mc.connection.getAutoCommit()) {
108                 mc.connection.setAutoCommit(true);
109             }
110         } catch (Exception JavaDoc exc) {
111             if (xares == null) {
112                 if (mc.trace.isLoggable(BasicLevel.DEBUG)) {
113                     mc.trace.log(BasicLevel.DEBUG,
114                             "Unable to set autoCommit to true:", exc);
115                 }
116             }
117         }
118     }
119
120     /**
121      * Ends the transaction
122      */

123     public void end(Xid JavaDoc xid, int flags) throws XAException JavaDoc {
124         if (mc.trace.isLoggable(BasicLevel.DEBUG)) {
125             mc.trace.log(BasicLevel.DEBUG, "" + xid + "," + flags);
126         }
127         // Make sure that the Xid has started
128
if (currentXid == null || !currentXid.equals(xid)) {
129             throw new XAException JavaDoc(XAException.XA_RBPROTO);
130         }
131         if (!started && ended) {
132             throw new XAException JavaDoc(XAException.XA_RBPROTO);
133         }
134         ended = true;
135         if (xares != null) {
136             xares.end(xid, flags);
137         }
138     }
139
140     /**
141      * Need to forget the heuristically completed Xid
142      */

143     public void forget(Xid JavaDoc xid) throws XAException JavaDoc {
144         if (mc.trace.isLoggable(BasicLevel.DEBUG)) {
145             mc.trace.log(BasicLevel.DEBUG, "" + xid);
146         }
147         if (xares != null) {
148             xares.forget(xid);
149         }
150     }
151
152     /**
153      * Get the current transaction timeout for this XAResource
154      */

155     public int getTransactionTimeout() throws XAException JavaDoc {
156         if (xares != null) {
157             return xares.getTransactionTimeout();
158         }
159         return 0;
160     }
161
162     /**
163      * Determine if the resource manager instance is the same as the
164      * resouce manager being passed in
165      */

166     public boolean isSameRM(XAResource JavaDoc xaRes) throws XAException JavaDoc {
167
168         boolean ret = false;
169         if (xaRes.equals(this)) {
170             ret = true;
171         } else if (!(xaRes instanceof XAResourceImpl)) {
172             ret = false;
173         } else {
174             XAResourceImpl xaResImpl = (XAResourceImpl) xaRes;
175             if (mc == xaResImpl.mc) {
176                 ret = true;
177             }
178         }
179         if (mc.trace.isLoggable(BasicLevel.DEBUG)) {
180             mc.trace.log(BasicLevel.DEBUG, "" + xaRes + "," + this + " is " + ret);
181         }
182         return ret;
183     }
184
185     /**
186      * Prepare the Xid for a transaction commit
187      */

188     public int prepare(Xid JavaDoc xid) throws XAException JavaDoc {
189         if (mc.trace.isLoggable(BasicLevel.DEBUG)) {
190             mc.trace.log(BasicLevel.DEBUG, "" + xid);
191         }
192         if (xares != null) {
193             int ret = xares.prepare(xid);
194             // If read-only, then do what would have been done in the commit call
195
if (ret == XA_RDONLY) {
196                 started = false;
197                 try {
198                     if (!mc.connection.getAutoCommit()) {
199                         mc.connection.setAutoCommit(true);
200                     }
201                 } catch (Exception JavaDoc exc) { }
202             }
203             return ret;
204         }
205         // Just return true, since we are just simulating XA with our wrapper
206
return XA_OK;
207     }
208
209     /**
210      * Obtain a list of prepared transaction branches from a resource manager.
211      */

212     public Xid JavaDoc[] recover(int flag) throws XAException JavaDoc {
213         if (mc.trace.isLoggable(BasicLevel.DEBUG)) {
214             mc.trace.log(BasicLevel.DEBUG, "" + flag);
215         }
216         if (xares != null) {
217             return xares.recover(flag);
218         }
219         // Not a full RM, so just return null
220
return null;
221     }
222
223     /**
224      * Roll back work done on the Xid
225      */

226     public void rollback(Xid JavaDoc xid) throws XAException JavaDoc {
227         if (mc.trace.isLoggable(BasicLevel.DEBUG)) {
228             mc.trace.log(BasicLevel.DEBUG, "" + xid);
229         }
230
231         // Rollback the Xid
232
try {
233             if (xares != null) {
234                 xares.rollback(xid);
235                 if (xid.equals(currentXid)) {
236                     started = false;
237                 }
238             } else {
239                 // Make sure that this call is for the XID
240
if (currentXid == null || !currentXid.equals(xid) || !started) {
241                     mc.trace.log(BasicLevel.ERROR, "passed xid(" + xid
242                                      + "),current Xid(" + currentXid
243                                      + "),started(" + started + ")");
244                     throw new XAException JavaDoc("Rollback: Must call correct XAResource for its started XID");
245                 }
246                 mc.connection.rollback();
247                 started = false;
248             }
249         } catch (XAException JavaDoc xe) {
250             mc.trace.log(BasicLevel.ERROR, xe.getMessage());
251             throw xe;
252         } catch (SQLException JavaDoc e) {
253             try {
254                 mc.trace.log(BasicLevel.ERROR, e.getMessage());
255                 mc.signalEvent(
256                     ConnectionEvent.CONNECTION_ERROR_OCCURRED, null, e);
257             } catch (Exception JavaDoc ex) {}
258             throw(new XAException JavaDoc("Error on rollback"));
259         }
260         try {
261             if (!mc.connection.getAutoCommit()) {
262                 mc.connection.setAutoCommit(true);
263             }
264         } catch (Exception JavaDoc exc) {
265             if (xares == null) {
266                 if (mc.trace.isLoggable(BasicLevel.DEBUG)) {
267                     mc.trace.log(BasicLevel.DEBUG,
268                             "Unable to set autoCommit to true:", exc);
269                 }
270             }
271         }
272     }
273
274     /**
275      * Set the current transaction timeout value for this XAResource
276      */

277     public boolean setTransactionTimeout(int seconds) throws XAException JavaDoc {
278         if (xares != null) {
279             return xares.setTransactionTimeout(seconds);
280         }
281         return false;
282     }
283
284     /**
285      * Start work on this Xid. If TMJOIN is on, then join an existing transaction
286      * already started by the RM.
287      */

288     public void start(Xid JavaDoc xid, int flags) throws XAException JavaDoc {
289         if (mc.trace.isLoggable(BasicLevel.DEBUG)) {
290             mc.trace.log(BasicLevel.DEBUG, "" + xid + "," + flags);
291         }
292         if (started && (currentXid == null || !currentXid.equals(xid))) {
293             mc.trace.log(BasicLevel.ERROR,
294                 "Must call correct XAResource for its started XID");
295             throw new XAException JavaDoc("XAResourceImpl.start : Must call correct XAResource for its started XID");
296         }
297         currentXid = xid;
298         started = true;
299         ended = false;
300         try {
301             if (mc.connection.getAutoCommit()) {
302                 mc.connection.setAutoCommit(false);
303             }
304         } catch (Exception JavaDoc ex) {
305             ex.printStackTrace();
306             mc.trace.log(BasicLevel.ERROR,
307                 "Unable to set autoCommit to false:" + ex.getMessage());
308             throw(new XAException JavaDoc(
309                 "Error : Unable to set autoCommit to false in start"));
310         }
311         if (xares != null) {
312             xares.start(xid, flags);
313         }
314     }
315 }
316
Popular Tags