KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > jdbc > standard > StandardXAConnectionHandle


1 /*
2  * XAPool: Open Source XA JDBC Pool
3  * Copyright (C) 2003 Objectweb.org
4  * Initial Developer: Lutris Technologies Inc.
5  * Contact: xapool-public@lists.debian-sf.objectweb.org
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20  * USA
21  */

22 package org.enhydra.jdbc.standard;
23
24 import java.sql.PreparedStatement JavaDoc;
25 import java.sql.SQLException JavaDoc;
26 import java.sql.Statement JavaDoc;
27 import java.sql.CallableStatement JavaDoc;
28 import java.util.Hashtable JavaDoc;
29 import javax.transaction.Transaction JavaDoc;
30 import javax.transaction.TransactionManager JavaDoc;
31 import javax.transaction.RollbackException JavaDoc;
32 import javax.transaction.SystemException JavaDoc;
33
34 public class StandardXAConnectionHandle extends StandardConnectionHandle {
35
36     boolean resetTxonResume =false;
37     boolean globalTransaction; // true if a global transaction is in effect
38
public TransactionManager JavaDoc transactionManager;
39     public Transaction JavaDoc tx;
40     public StandardXAConnection xacon;
41     public boolean thisAutoCommit = true;
42
43     /**
44      * Constructor
45      */

46     public StandardXAConnectionHandle(
47         StandardXAConnection pooledCon,
48         Hashtable JavaDoc preparedStatementCache,
49         int preparedStmtCacheSize,
50         TransactionManager JavaDoc tm) {
51         super(pooledCon, preparedStatementCache, preparedStmtCacheSize);
52         // setup StandardXAConnectionHandle
53
xacon = pooledCon;
54         transactionManager = tm;
55         log = pooledCon.dataSource.log;
56
57         // This will have set the Connection to the current Connection.
58
// However this might change if a global transaction gets selected.
59
}
60
61     public void setTransactionManager(TransactionManager JavaDoc tm) {
62         this.transactionManager = tm;
63     }
64
65     synchronized public void close() throws SQLException JavaDoc {
66         Transaction JavaDoc ttx = tx;
67         // note: ttx is used instead of tx because super.close(), call end()
68
// on StdXAConnection which call tx = null;
69
super.close();
70         log.debug("StandardXAConnectionHandle:close");
71         log.debug(
72             "StandardXAConnectionHandle:close globalTransaction='"
73                 + globalTransaction
74                 + "' con.getAutoCommit='"
75                 + con.getAutoCommit()
76                 + "' ttx='"
77                 + ttx
78                 + "'");
79
80         if ((!con.getAutoCommit()) && (ttx == null)) {
81             log.debug(
82                 "StandardXAConnectionHandle:close rollback the connection");
83             con.rollback();
84             con.setAutoCommit(thisAutoCommit);
85         } else
86             log.debug("StandardXAConnectionHandle:close do nothing else");
87         isReallyUsed = false;
88         log.debug(
89             "StandardXAConnectionHandle:close AFTER globalTransaction='"
90                 + globalTransaction
91                 + "' con.getAutoCommit='"
92                 + con.getAutoCommit()
93                 + "' ttx='"
94                 + ttx
95                 + "'");
96     }
97
98     /**
99      * Called by the StandardXADataSource when a global transaction
100      * gets associated with this connection.
101      */

102     void setGlobalTransaction(boolean setting) throws SQLException JavaDoc {
103         log.debug(
104             "StandardXAConnectionHandle:setGlobalTransaction gTransaction='"
105                 + setting
106                 + "'");
107         globalTransaction = setting; // set global flag
108
con = pooledCon.getPhysicalConnection(); // get the real connection
109
if (con == null)
110             log.warn(
111                 "StandardXAConnectionHandle:setGlobalTransaction con is null before setupPreparedStatementCache");
112         else
113             log.debug(
114                 "StandardXAConnectionHandle:setGlobalTransaction con is *NOT* null before setupPreparedStatementCache");
115         //setupPreparedStatementCache();
116
if(!isClosed())
117             super.setAutoCommit(!setting);
118         // commits must be done by transaction manager
119
}
120
121     public void setAutoCommit(boolean autoCommit) throws SQLException JavaDoc {
122         if (globalTransaction) // if taking part in a global transaction
123
throw new SQLException JavaDoc("StandardXAConnectionHandle:setAutoCommit This connection is part of a global transaction");
124         super.setAutoCommit(autoCommit);
125     }
126
127     public void commit() throws SQLException JavaDoc {
128         if (globalTransaction) // if taking part in a global transaction
129
throw new SQLException JavaDoc("StandardXAConnectionHandle:commit:This connection is part of a global transaction");
130         super.commit();
131         //tx = null;
132
}
133
134     public void rollback() throws SQLException JavaDoc {
135         if (globalTransaction) // if taking part in a global transaction
136
throw new SQLException JavaDoc("StandardXAConnectionHandle:rollback:This connection is part of a global transaction");
137         super.rollback();
138         //tx = null;
139
}
140
141     synchronized PreparedStatement JavaDoc checkPreparedCache(
142         String JavaDoc sql,
143         int type,
144         int concurrency,
145         int holdability,
146         Object JavaDoc lookupKey)
147         throws SQLException JavaDoc {
148         PreparedStatement JavaDoc ret = null; // the return value
149
// NOTE - We include the Connection in the lookup key. This has no
150
// effect here but is needed by StandardXAConnection where the the physical
151
// Connection used can vary over time depending on the global transaction.
152
if (preparedStatementCache != null) {
153             Object JavaDoc obj = preparedStatementCache.get(lookupKey);
154             // see if there's a PreparedStatement already
155
if (obj != null) { // if there is
156
log.debug(
157                     "StandardXAConnectionHandle:checkPreparedCache object is found");
158                 ret = (PreparedStatement JavaDoc) obj; // use as return value
159
try {
160                     ret.clearParameters(); // make it look like new
161
} catch (SQLException JavaDoc e) {
162                     // Bad statement, so we have to create a new one
163
ret = createPreparedStatement(sql, type, concurrency, holdability);
164                     // create new prepared statement
165
}
166                 preparedStatementCache.remove(lookupKey);
167                 // make sure it cannot be re-used
168
inUse.put(lookupKey, ret);
169                 // make sure it gets reused by later delegates
170
} else { // no PreparedStatement ready
171
log.debug(
172                     "StandardXAConnectionHandle:checkPreparedCache object is *NOT* found");
173                 ret = createPreparedStatement(sql, type, concurrency, holdability);
174                 // create new prepared statement
175
inUse.put(lookupKey, ret);
176                 // will get saved in prepared statement cache
177
}
178         } else {
179             log.debug(
180                 "StandardXAConnectionHandle:checkPreparedCache object the cache is out");
181             ret = createPreparedStatement(sql, type, concurrency, holdability);
182             // create new prepared statement
183
}
184         // We don't actually give the application a real PreparedStatement. Instead
185
// they get a StandardPreparedStatement that delegates everything except
186
// PreparedStatement.close();
187
log.debug(
188             "StandardXAConnectionHandle:checkPreparedCache pstmt='"
189                 + ret.toString()
190                 + "'");
191         return ret;
192     }
193
194
195
196     synchronized PreparedStatement JavaDoc checkPreparedCache(
197         String JavaDoc sql,
198         int autogeneratedkeys,
199         Object JavaDoc lookupKey)
200         throws SQLException JavaDoc {
201         PreparedStatement JavaDoc ret = null; // the return value
202
// NOTE - We include the Connection in the lookup key. This has no
203
// effect here but is needed by StandardXAConnection where the the physical
204
// Connection used can vary over time depending on the global transaction.
205
if (preparedStatementCache != null) {
206             Object JavaDoc obj = preparedStatementCache.get(lookupKey);
207             // see if there's a PreparedStatement already
208
if (obj != null) { // if there is
209
log.debug(
210                     "StandardXAConnectionHandle:checkPreparedCache object is found");
211                 ret = (PreparedStatement JavaDoc) obj; // use as return value
212
try {
213                     ret.clearParameters(); // make it look like new
214
} catch (SQLException JavaDoc e) {
215                     // Bad statement, so we have to create a new one
216
ret = createPreparedStatement(sql, autogeneratedkeys);
217                     // create new prepared statement
218
}
219                 preparedStatementCache.remove(lookupKey);
220                 // make sure it cannot be re-used
221
inUse.put(lookupKey, ret);
222                 // make sure it gets reused by later delegates
223
} else { // no PreparedStatement ready
224
log.debug(
225                     "StandardXAConnectionHandle:checkPreparedCache object is *NOT* found");
226                 ret = createPreparedStatement(sql, autogeneratedkeys);
227                 // create new prepared statement
228
inUse.put(lookupKey, ret);
229                 // will get saved in prepared statement cache
230
}
231         } else {
232             log.debug(
233                 "StandardXAConnectionHandle:checkPreparedCache object the cache is out");
234             ret = createPreparedStatement(sql, autogeneratedkeys);
235             // create new prepared statement
236
}
237         // We don't actually give the application a real PreparedStatement. Instead
238
// they get a StandardPreparedStatement that delegates everything except
239
// PreparedStatement.close();
240
log.debug(
241             "StandardXAConnectionHandle:checkPreparedCache pstmt='"
242                 + ret.toString()
243                 + "'");
244         return ret;
245     }
246
247
248
249     /**
250      * Creates a PreparedStatement for the given SQL. If possible, the
251      * statement is fetched from the cache.
252      */

253     public PreparedStatement JavaDoc prepareStatement(String JavaDoc sql) throws SQLException JavaDoc {
254         return prepareStatement(sql, 0, 0, 0);
255     }
256
257     public PreparedStatement JavaDoc prepareStatement(
258         String JavaDoc sql,
259         int resultSetType,
260         int resultSetConcurrency)
261         throws SQLException JavaDoc {
262         return prepareStatement(sql, resultSetType, resultSetConcurrency, 0);
263     }
264
265     /**
266      * Creates a PreparedStatement for the given SQL, type and concurrency.
267      * If possible, the statement is fetched from the cache.
268      */

269     public PreparedStatement JavaDoc prepareStatement(
270         String JavaDoc sql,
271         int resultSetType,
272         int resultSetConcurrency,
273         int resultSetHoldability)
274         throws SQLException JavaDoc {
275         if (tx == null) {
276             log.debug("StandardXAConnectionHandle:prepareStatement tx==null");
277             try {
278                 try {
279                     Transaction JavaDoc ntx = this.getTransaction();
280                     if (ntx != null) {
281                         log.debug(
282                             "StandardXAConnectionHandle:prepareStatement (found a transaction)");
283                         tx = ntx;
284                         xacon.thisAutoCommit = this.getAutoCommit();
285                         if (this.getAutoCommit()) {
286                             this.setAutoCommit(false);
287                         }
288                         try {
289                             tx.enlistResource(xacon.getXAResource());
290                             // enlist the xaResource in the transaction
291
} catch (RollbackException JavaDoc n) {
292                             log.debug(
293                                 "StandardXAConnectionHandle:prepareStatemnet enlistResource exception : "
294                                     + n.toString());
295                         }
296                     } else {
297                         log.debug(
298                             "StandardXAConnectionHandle:prepareStatement (no transaction found)");
299                     }
300                 } catch (SystemException JavaDoc n) {
301                     n.printStackTrace();
302                     throw new SQLException JavaDoc(
303                         "StandardXAConnectionHandle:prepareStatement getTransaction exception: "
304                             + n.toString());
305                 }
306             } catch (NullPointerException JavaDoc n) {
307                 // current is null: we are not in EJBServer.
308
n.printStackTrace();
309                 throw new SQLException JavaDoc("StandardXAConnectionHandle:prepareStatement should not be used outside an EJBServer");
310             }
311         } else
312             log.debug("StandardXAConnectionHandle:prepareStatement tx!=null");
313
314         // if you want to use a REAL PrepareStatement object, please
315
// uncomment the 2 following lines and comment the last ones.
316
//PreparedStatement ops = con.prepareStatement(sql, resultSetType, resultSetConcurrency);
317
//return ops;
318

319         isReallyUsed = true;
320         return new StandardXAPreparedStatement(
321             this,
322             sql,
323             resultSetType,
324             resultSetConcurrency,
325             resultSetHoldability);
326     }
327
328         public PreparedStatement JavaDoc prepareStatement(String JavaDoc sql, int autoGeneratedKeys)
329         throws SQLException JavaDoc {
330         if (tx == null) {
331         log.debug("StandardXAConnectionHandle:prepareStatement tx==null");
332         try {
333             try {
334             Transaction JavaDoc ntx = this.getTransaction();
335             if (ntx != null) {
336                 log.debug(
337                       "StandardXAConnectionHandle:prepareStatement (found a transaction)");
338                 tx = ntx;
339                 xacon.thisAutoCommit = this.getAutoCommit();
340                 if (this.getAutoCommit()) {
341                 this.setAutoCommit(false);
342                 }
343                 try {
344                 tx.enlistResource(xacon.getXAResource());
345                 // enlist the xaResource in the transaction
346
} catch (RollbackException JavaDoc n) {
347                 log.debug(
348                       "StandardXAConnectionHandle:prepareStatemnet enlistResource exception : "
349                       + n.toString());
350                 }
351             } else {
352                 log.debug(
353                       "StandardXAConnectionHandle:prepareStatement (no transaction found)");
354             }
355             } catch (SystemException JavaDoc n) {
356             n.printStackTrace();
357             throw new SQLException JavaDoc(
358                            "StandardXAConnectionHandle:prepareStatement getTransaction exception: "
359                            + n.toString());
360             }
361         } catch (NullPointerException JavaDoc n) {
362             // current is null: we are not in EJBServer.
363
n.printStackTrace();
364             throw new SQLException JavaDoc("StandardXAConnectionHandle:prepareStatement should not be used outside an EJBServer");
365         }
366         } else
367         log.debug("StandardXAConnectionHandle:prepareStatement tx!=null");
368         
369         isReallyUsed = true;
370         return new StandardXAPreparedStatement(
371                            this,
372                            sql,
373                            autoGeneratedKeys);
374     }
375     
376        /**
377     * not yet implemented
378     */

379         public PreparedStatement JavaDoc prepareStatement(String JavaDoc sql, int[] columnIndexes) throws SQLException JavaDoc {
380         throw new UnsupportedOperationException JavaDoc();
381     }
382
383        /**
384     * not yet implemented
385     */

386         public PreparedStatement JavaDoc prepareStatement(String JavaDoc sql, String JavaDoc[] columnNames) throws SQLException JavaDoc {
387         throw new UnsupportedOperationException JavaDoc();
388     }
389
390
391     /**
392      * Creates a CallableStatement for the given SQL, result set type and concurency
393      */

394     public CallableStatement JavaDoc prepareCall(
395         String JavaDoc sql,
396         int resultSetType,
397         int resultSetConcurrency)
398         throws SQLException JavaDoc {
399         return new StandardXACallableStatement(
400             this,
401             sql,
402             resultSetType,
403             resultSetConcurrency, 0);
404     }
405
406     /**
407      * Creates a CallableStatement for the given SQL
408      */

409     public CallableStatement JavaDoc prepareCall(String JavaDoc sql) throws SQLException JavaDoc {
410         return new StandardXACallableStatement(this, sql, 0, 0, 0);
411     }
412
413         public CallableStatement JavaDoc prepareCall(String JavaDoc sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability)
414         throws SQLException JavaDoc {
415         return new StandardXACallableStatement(
416             this,
417             sql,
418             resultSetType,
419             resultSetConcurrency,
420             resultSetHoldability);
421     }
422
423
424     public Statement JavaDoc createStatement() throws SQLException JavaDoc {
425         return createStatement(0,0,0);
426     }
427
428     public Statement JavaDoc createStatement(
429         int resultSetType,
430         int resultSetConcurrency)
431         throws SQLException JavaDoc {
432         return createStatement(resultSetType, resultSetConcurrency, 0);
433     }
434
435     public Statement JavaDoc createStatement(
436         int resultSetType,
437         int resultSetConcurrency,
438         int resultSetHoldability)
439         throws SQLException JavaDoc {
440
441         if (tx == null) {
442             log.debug("StandardXAConnectionHandle:createStatement tx==null");
443             try {
444                 try {
445                     Transaction JavaDoc ntx = this.getTransaction();
446                     if (ntx != null) {
447                         log.debug(
448                             "StandardXAConnectionHandle:createStatement (found a transaction)");
449                         tx = ntx;
450                         xacon.thisAutoCommit = this.getAutoCommit();
451                         if (this.getAutoCommit()) {
452                             this.setAutoCommit(false);
453                         }
454                         try {
455                             tx.enlistResource(xacon.getXAResource());
456                             // enlist the xaResource in the transaction
457
} catch (RollbackException JavaDoc n) {
458                             log.debug(
459                                 "StandardXAConnectionHandle:createStatement enlistResource exception: "
460                                     + n.toString());
461                         }
462                     } else {
463                         log.debug(
464                             "StandardXAConnectionHandle:createStatement (no transaction found)");
465                     }
466
467                 } catch (SystemException JavaDoc n) {
468                     throw new SQLException JavaDoc(
469                         "StandardXAConnectionHandle:createStatement getTransaction exception: "
470                             + n.toString());
471                 }
472             } catch (NullPointerException JavaDoc n) {
473                 // current is null: we are not in EJBServer.
474
throw new SQLException JavaDoc(
475                     "StandardXAConnectionHandle:createStatement should not be used outside an EJBServer: "
476                         + n.toString());
477             }
478         }
479         isReallyUsed = true;
480         return new StandardXAStatement(this, resultSetType, resultSetConcurrency, resultSetHoldability);
481     }
482
483     private Transaction JavaDoc getTransaction() throws SystemException JavaDoc {
484         Transaction JavaDoc ntx = null;
485         if (transactionManager != null) {
486             ntx = transactionManager.getTransaction();
487         } else {
488             log.debug(
489                 "StandardXAConnectionHandle:getTransaction (null transaction manager)");
490         }
491
492         return ntx;
493     }
494     
495     public String JavaDoc toString() {
496         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
497         sb.append("StandardXAConnectionHandle:\n");
498         sb.append(" global transaction =<"+this.globalTransaction+ ">\n");
499         sb.append(" is really used =<"+this.isReallyUsed+ ">\n");
500         sb.append(" this autoCommit =<"+this.thisAutoCommit+ ">\n");
501         sb.append(" in use size =<"+this.inUse.size()+ ">\n");
502         sb.append(" master prepared stmt cache size =<"+this.masterPrepStmtCache.size()+ ">\n");
503         sb.append(" transaction =<"+this.tx+ ">\n");
504         sb.append(" connection =<"+this.con.toString()+ ">\n");
505         
506         return sb.toString();
507     }
508 }
509
Popular Tags