Source Code Cross Referenced for EmbedXAResource.java in  » Database-DBMS » db-derby-10.2 » org » apache » derby » jdbc » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database DBMS » db derby 10.2 » org.apache.derby.jdbc 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:
003:           Derby - Class org.apache.derby.jdbc.EmbedXAResource
004:
005:           Licensed to the Apache Software Foundation (ASF) under one or more
006:           contributor license agreements.  See the NOTICE file distributed with
007:           this work for additional information regarding copyright ownership.
008:           The ASF licenses this file to You under the Apache License, Version 2.0
009:           (the "License"); you may not use this file except in compliance with
010:           the License.  You may obtain a copy of the License at
011:
012:              http://www.apache.org/licenses/LICENSE-2.0
013:
014:           Unless required by applicable law or agreed to in writing, software
015:           distributed under the License is distributed on an "AS IS" BASIS,
016:           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017:           See the License for the specific language governing permissions and
018:           limitations under the License.
019:
020:         */
021:
022:        package org.apache.derby.jdbc;
023:
024:        import java.sql.SQLException;
025:        import javax.transaction.xa.XAResource;
026:        import javax.transaction.xa.Xid;
027:        import javax.transaction.xa.XAException;
028:
029:        import org.apache.derby.iapi.error.StandardException;
030:        import org.apache.derby.iapi.jdbc.BrokeredConnection;
031:        import org.apache.derby.iapi.jdbc.ResourceAdapter;
032:        import org.apache.derby.iapi.reference.SQLState;
033:        import org.apache.derby.iapi.reference.JDBC30Translation;
034:        import org.apache.derby.iapi.services.context.ContextManager;
035:        import org.apache.derby.iapi.services.context.ContextService;
036:        import org.apache.derby.iapi.services.info.JVMInfo;
037:        import org.apache.derby.iapi.store.access.XATransactionController;
038:        import org.apache.derby.iapi.store.access.xa.XAResourceManager;
039:        import org.apache.derby.iapi.store.access.xa.XAXactId;
040:        import org.apache.derby.impl.jdbc.EmbedConnection;
041:        import org.apache.derby.impl.jdbc.TransactionResourceImpl;
042:
043:        /**
044:         * Implements XAResource
045:         */
046:        class EmbedXAResource implements  XAResource {
047:
048:            private EmbedPooledConnection con;
049:            private ResourceAdapter ra;
050:            private XAXactId currentXid;
051:
052:            EmbedXAResource(EmbedPooledConnection con, ResourceAdapter ra) {
053:                this .con = con;
054:                this .ra = ra;
055:            }
056:
057:            /**
058:             * Commit the global transaction specified by xid.
059:             * @param xid A global transaction identifier
060:             * @param onePhase If true, the resource manager should use a one-phase
061:             * commit protocol to commit the work done on behalf of xid.
062:
063:             * @exception XAException An error has occurred. Possible XAExceptions are
064:             * XA_HEURHAZ, XA_HEURCOM, XA_HEURRB, XA_HEURMIX, XAER_RMERR,
065:             * XAER_RMFAIL, XAER_NOTA, XAER_INVAL, or XAER_PROTO.  
066:             * <P>If the resource manager did not commit the transaction and
067:             * the paramether onePhase is set to true, the resource manager 
068:             * may throw one of the XA_RB* exceptions. Upon return, the
069:             * resource manager has rolled back the branch's work and has 
070:             * released all held resources.
071:             */
072:            public final synchronized void commit(Xid xid, boolean onePhase)
073:                    throws XAException {
074:                checkXAActive();
075:                // ensure immtable and correct equals method.
076:                XAXactId xid_im = new XAXactId(xid);
077:                XATransactionState tranState = getTransactionState(xid_im);
078:
079:                if (tranState == null) {
080:                    XAResourceManager rm = ra.getXAResourceManager();
081:                    ContextManager inDoubtCM = rm.find(xid);
082:                    // RM also does not know about this xid.
083:                    if (inDoubtCM == null)
084:                        throw new XAException(XAException.XAER_NOTA);
085:                    ContextService csf = ContextService.getFactory();
086:                    csf.setCurrentContextManager(inDoubtCM);
087:                    try {
088:                        rm.commit(inDoubtCM, xid_im, onePhase);
089:
090:                        // close the connection/transaction since it can never
091:                        // be used again.
092:                        inDoubtCM.cleanupOnError(StandardException
093:                                .closeException());
094:                        return;
095:                    } catch (StandardException se) {
096:                        // The rm threw an exception, clean it up in the approprate
097:                        // context.  There is no transactionResource to handle the
098:                        // exception for us.
099:                        inDoubtCM.cleanupOnError(se);
100:                        throw wrapInXAException(se);
101:                    } finally {
102:                        csf.resetCurrentContextManager(inDoubtCM);
103:                    }
104:
105:                }
106:
107:                synchronized (tranState) {
108:                    checkUserCredentials(tranState.creatingResource);
109:
110:                    // Check the transaction is no associated with
111:                    // any XAResource.
112:                    switch (tranState.associationState) {
113:                    case XATransactionState.T0_NOT_ASSOCIATED:
114:                        break;
115:
116:                    case XATransactionState.TRO_FAIL:
117:                        throw new XAException(tranState.rollbackOnlyCode);
118:
119:                    default:
120:                        throw new XAException(XAException.XAER_PROTO);
121:                    }
122:
123:                    if (tranState.suspendedList != null
124:                            && tranState.suspendedList.size() != 0)
125:                        throw new XAException(XAException.XAER_PROTO);
126:
127:                    if (tranState.isPrepared == onePhase)
128:                        throw new XAException(XAException.XAER_PROTO);
129:
130:                    EmbedConnection conn = tranState.conn;
131:
132:                    try {
133:                        conn.xa_commit(onePhase);
134:                    } catch (SQLException sqle) {
135:                        throw wrapInXAException(sqle);
136:                    } finally {
137:                        returnConnectionToResource(tranState, xid_im);
138:                    }
139:                }
140:            }
141:
142:            /**
143:             * Ends the work performed on behalf of a transaction branch. The resource
144:             * manager disassociates the XA resource from the transaction branch
145:             * specified and let the transaction be completed.
146:             *
147:             * <p> If TMSUSPEND is specified in flags, the transaction branch is
148:             * temporarily suspended in incomplete state. The transaction context
149:             * is in suspened state and must be resumed via start with TMRESUME
150:             * specified.
151:             *
152:             * <p> If TMFAIL is specified, the portion of work has failed. The
153:             * resource manager may mark the transaction as rollback-only
154:             *
155:             * <p> If TMSUCCESS is specified, the portion of work has completed
156:             * successfully.
157:             *
158:             * @param xid A global transaction identifier that is the same as what was
159:             * used previously in the start method.
160:             * @param flags One of TMSUCCESS, TMFAIL, or TMSUSPEND
161:             *
162:             * @exception XAException An error has occurred.
163:             * Possible XAException values are XAER_RMERR, XAER_RMFAILED, XAER_NOTA,
164:             * XAER_INVAL, XAER_PROTO, or XA_RB*.
165:             */
166:            public final synchronized void end(Xid xid, int flags)
167:                    throws XAException {
168:                checkXAActive();
169:
170:                try {
171:                    // It is possible that the isolation level state in connection
172:                    // handle has gotten out of sync with the real isolation level.
173:                    // This can happen if SLQ instead of JDBC api has been used to
174:                    // set the isolation level. The code below will check if isolation
175:                    // was set using JDBC or SQL and if yes, then it will update the
176:                    // isolation state in BrokeredConnection with EmbedConnection's
177:                    // isolation level.
178:                    if (con.currentConnectionHandle != null)
179:                        con.currentConnectionHandle.getIsolationUptoDate();
180:                } catch (SQLException sqle) {
181:                    throw wrapInXAException(sqle);
182:                }
183:
184:                // ensure immtable and correct equals method.
185:                XAXactId xid_im = new XAXactId(xid);
186:
187:                boolean endingCurrentXid = false;
188:
189:                // must match the Xid from start()
190:                if (currentXid != null) {
191:                    if (!currentXid.equals(xid_im))
192:                        throw new XAException(XAException.XAER_PROTO);
193:                    endingCurrentXid = true;
194:                }
195:
196:                XATransactionState tranState = getTransactionState(xid_im);
197:                if (tranState == null)
198:                    throw new XAException(XAException.XAER_NOTA);
199:
200:                boolean rollbackOnly = tranState.end(this , flags,
201:                        endingCurrentXid);
202:
203:                // RESOLVE - what happens to the connection on a fail
204:                // where we are not ending the current XID.
205:                if (endingCurrentXid) {
206:                    currentXid = null;
207:                    con.realConnection = null;
208:                }
209:
210:                if (rollbackOnly)
211:                    throw new XAException(tranState.rollbackOnlyCode);
212:            }
213:
214:            /**
215:             * Ask the resource manager to prepare for a transaction commit of the
216:             * transaction specified in xid.
217:             *
218:             * @param xid A global transaction identifier
219:             *
220:             * @return A value indicating the resource manager's vote on the outcome
221:             * of the transaction. The possible values are: XA_RDONLY or XA_OK. If the
222:             * resource manager wants to roll back the transaction, it should do so by
223:             * raising an appropriate XAException in the prepare method.
224:             *
225:             * @exception XAException An error has occurred. Possible exception values
226:             * are: XA_RB*, XAER_RMERR, XAER_RMFAIL, XAER_NOTA, XAER_INVAL, or
227:             * XAER_PROTO.
228:             *
229:             */
230:            public final synchronized int prepare(Xid xid) throws XAException {
231:                checkXAActive();
232:
233:                // ensure immtable and correct equals method.
234:                XAXactId xid_im = new XAXactId(xid);
235:
236:                XATransactionState tranState = getTransactionState(xid_im);
237:
238:                if (tranState == null) {
239:                    XAResourceManager rm = ra.getXAResourceManager();
240:
241:                    ContextManager inDoubtCM = rm.find(xid);
242:
243:                    // RM also does not know about this xid.
244:                    if (inDoubtCM == null)
245:                        throw new XAException(XAException.XAER_NOTA);
246:
247:                    // cannot prepare in doubt transactions
248:                    throw new XAException(XAException.XAER_PROTO);
249:
250:                }
251:
252:                synchronized (tranState) {
253:
254:                    checkUserCredentials(tranState.creatingResource);
255:
256:                    // Check the transaction is no associated with
257:                    // any XAResource.
258:                    switch (tranState.associationState) {
259:                    case XATransactionState.T0_NOT_ASSOCIATED:
260:                        break;
261:
262:                    case XATransactionState.TRO_FAIL:
263:                        throw new XAException(tranState.rollbackOnlyCode);
264:
265:                    default:
266:                        throw new XAException(XAException.XAER_PROTO);
267:                    }
268:
269:                    if (tranState.suspendedList != null
270:                            && tranState.suspendedList.size() != 0)
271:                        throw new XAException(XAException.XAER_PROTO);
272:
273:                    if (tranState.isPrepared)
274:                        throw new XAException(XAException.XAER_PROTO);
275:
276:                    EmbedConnection conn = tranState.conn;
277:
278:                    try {
279:
280:                        int ret = conn.xa_prepare();
281:
282:                        if (ret == XATransactionController.XA_OK) {
283:                            tranState.isPrepared = true;
284:
285:                            return XAResource.XA_OK;
286:                        } else {
287:
288:                            returnConnectionToResource(tranState, xid_im);
289:                            return XAResource.XA_RDONLY;
290:                        }
291:                    } catch (SQLException sqle) {
292:                        throw wrapInXAException(sqle);
293:                    }
294:                }
295:
296:            }
297:
298:            /**
299:             * Obtain the current transaction timeout value set for this XAResource
300:             * instance. If XAResource.setTransactionTimeout was not use prior to
301:             * invoking this method, the return value is the default timeout set for
302:             * the resource manager; otherwise, the value used in the previous
303:             * setTransactionTimeout call is returned.
304:             *
305:             * @return the transaction timeout value in seconds.
306:             */
307:            public int getTransactionTimeout() {
308:                return 0;
309:            }
310:
311:            /**
312:             * This method is called to determine if the resource manager instance
313:             * represented by the target object is the same as the resouce manager
314:             * instance represented by the parameter xares.
315:             *
316:             * @param xares An XAResource object whose resource manager instance is to
317:             * be compared with the resource manager instance of the target object.
318:             *
319:             * @return true if it's the same RM instance; otherwise false.
320:             * @exception XAException An error has occurred. Possible exception values
321:             * are XAER_RMERR, XAER_RMFAIL.
322:             */
323:            public final synchronized boolean isSameRM(XAResource xares)
324:                    throws XAException {
325:                checkXAActive();
326:                if (xares instanceof  EmbedXAResource) {
327:                    return ra == ((EmbedXAResource) xares).ra;
328:                }
329:                return false;
330:            }
331:
332:            /**
333:             * Obtain a list of prepared transaction branches from a resource
334:             * manager. The transaction manager calls this method during recovery to
335:             * obtain the list of transaction branches that are currently in prepared
336:             * or heuristically completed states.
337:             *
338:             * @param flag One of TMSTARTRSCAN, TMENDRSCAN, TMNOFLAGS. TMNOFLAGS must
339:             * be used when no other flags are set in flags.
340:             *
341:             * @return The resource manager returns zero or more XIDs for the
342:             * transaction branches that are currently in a prepared or heuristically
343:             * completed state. If an error occurs during the operation, the resource
344:             * manager should throw the appropriate XAException.
345:             *
346:             * @exception XAException An error has occurred. Possible values are
347:             * XAER_RMERR, XAER_RMFAIL, XAER_INVAL, and XAER_PROTO.
348:             *
349:             */
350:            public final synchronized Xid[] recover(int flag)
351:                    throws XAException {
352:                checkXAActive();
353:
354:                try {
355:                    return ra.getXAResourceManager().recover(flag);
356:                } catch (StandardException se) {
357:                    throw wrapInXAException(se);
358:                }
359:            }
360:
361:            /**
362:             * Tell the resource manager to forget about a heuristically completed
363:             * transaction branch.
364:             *
365:             * @param xid A global transaction identifier
366:             * @exception XAException An error has occurred. Possible exception values
367:             * are XAER_RMERR, XAER_RMFAIL, XAER_NOTA, XAER_INVAL, or XAER_PROTO.
368:             */
369:            public final synchronized void forget(Xid xid) throws XAException {
370:
371:                checkXAActive();
372:
373:                // ensure immtable and correct equals method.
374:                XAXactId xid_im = new XAXactId(xid);
375:
376:                XATransactionState tranState = getTransactionState(xid_im);
377:                if (tranState == null) {
378:                    XAResourceManager rm = ra.getXAResourceManager();
379:
380:                    ContextManager inDoubtCM = rm.find(xid);
381:
382:                    // RM also does not know about this xid.
383:                    if (inDoubtCM == null)
384:                        throw new XAException(XAException.XAER_NOTA);
385:
386:                    ContextService csf = ContextService.getFactory();
387:
388:                    csf.setCurrentContextManager(inDoubtCM);
389:                    try {
390:                        rm.forget(inDoubtCM, xid_im);
391:
392:                        // close the connection/transaction since it can never be used again.
393:                        inDoubtCM.cleanupOnError(StandardException
394:                                .closeException());
395:                        return;
396:                    } catch (StandardException se) {
397:                        // The rm threw an exception, clean it up in the approprate
398:                        // context.  There is no transactionResource to handle the
399:                        // exception for us.
400:                        inDoubtCM.cleanupOnError(se);
401:                        throw wrapInXAException(se);
402:                    } finally {
403:                        csf.resetCurrentContextManager(inDoubtCM);
404:                    }
405:
406:                }
407:
408:                throw new XAException(
409:                        tranState.isPrepared ? XAException.XAER_NOTA
410:                                : XAException.XAER_PROTO);
411:            }
412:
413:            /**
414:             * Inform the resource manager to roll back work done on behalf of a
415:             * transaction branch
416:             *
417:             * @param xid A global transaction identifier
418:             * @exception XAException - An error has occurred
419:             */
420:            public final synchronized void rollback(Xid xid) throws XAException {
421:                checkXAActive();
422:
423:                // ensure immtable and correct equals method.
424:                XAXactId xid_im = new XAXactId(xid);
425:
426:                XATransactionState tranState = getTransactionState(xid_im);
427:
428:                if (tranState == null) {
429:                    XAResourceManager rm = ra.getXAResourceManager();
430:
431:                    ContextManager inDoubtCM = rm.find(xid);
432:
433:                    // RM also does not know about this xid.
434:                    if (inDoubtCM == null)
435:                        throw new XAException(XAException.XAER_NOTA);
436:
437:                    ContextService csf = ContextService.getFactory();
438:
439:                    csf.setCurrentContextManager(inDoubtCM);
440:                    try {
441:                        rm.rollback(inDoubtCM, xid_im);
442:
443:                        // close the connection/transaction since it can never be used again.
444:                        inDoubtCM.cleanupOnError(StandardException
445:                                .closeException());
446:                        return;
447:                    } catch (StandardException se) {
448:                        // The rm threw an exception, clean it up in the approprate
449:                        // context.  There is no transactionResource to handle the
450:                        // exception for us.
451:                        inDoubtCM.cleanupOnError(se);
452:                        throw wrapInXAException(se);
453:                    } finally {
454:                        csf.resetCurrentContextManager(inDoubtCM);
455:                    }
456:
457:                }
458:
459:                synchronized (tranState) {
460:
461:                    // Check the transaction is no associated with
462:                    // any XAResource.
463:                    switch (tranState.associationState) {
464:                    case XATransactionState.T0_NOT_ASSOCIATED:
465:                    case XATransactionState.TRO_FAIL:
466:                        break;
467:
468:                    default:
469:                        throw new XAException(XAException.XAER_PROTO);
470:                    }
471:
472:                    if (tranState.suspendedList != null
473:                            && tranState.suspendedList.size() != 0)
474:                        throw new XAException(XAException.XAER_PROTO);
475:
476:                    checkUserCredentials(tranState.creatingResource);
477:
478:                    try {
479:
480:                        tranState.conn.xa_rollback();
481:                    } catch (SQLException sqle) {
482:                        throw wrapInXAException(sqle);
483:                    } finally {
484:                        returnConnectionToResource(tranState, xid_im);
485:                    }
486:                }
487:            }
488:
489:            /**
490:             * Set the current transaction timeout value for this XAResource
491:             * instance. Once set, this timeout value is effective until
492:             * setTransactionTimeout is invoked again with a different value. To reset
493:             * the timeout value to the default value used by the resource manager,
494:             * set the value to zero. If the timeout operation is performed
495:             * successfully, the method returns true; otherwise false. If a resource
496:             * manager does not support transaction timeout value to be set
497:             * explicitly, this method returns false.
498:             *
499:             * @param seconds the transaction timeout value in seconds.
500:             * @return true if transaction timeout value is set successfully;
501:             * otherwise false.
502:             *
503:             * @exception XAException - An error has occurred. Possible exception
504:             * values are XAER_RMERR, XAER_RMFAIL, or XAER_INVAL.
505:             */
506:            public boolean setTransactionTimeout(int seconds) {
507:                return false;
508:            }
509:
510:            /**
511:             * Start work on behalf of a transaction branch specified in xid If TMJOIN
512:             * is specified, the start is for joining a transaction previously seen by
513:             * the resource manager. If TMRESUME is specified, the start is to resume
514:             * a suspended transaction specified in the parameter xid. If neither
515:             * TMJOIN nor TMRESUME is specified and the transaction specified by xid
516:             * has previously been seen by the resource manager, the resource manager
517:             * throws the XAException exception with XAER_DUPID error code.
518:             *
519:             * @param xid A global transaction identifier to be associated with the
520:             * resource
521:             * @param flags One of TMNOFLAGS, TMJOIN, or TMRESUME
522:             *
523:             * @exception XAException An error has occurred. Possible exceptions are
524:             * XA_RB*, XAER_RMERR, XAER_RMFAIL, XAER_DUPID, XAER_OUTSIDE, XAER_NOTA,
525:             * XAER_INVAL, or XAER_PROTO.
526:             */
527:            public final synchronized void start(Xid xid, int flags)
528:                    throws XAException {
529:                checkXAActive();
530:
531:                // JDBC 3.0 section 12.3 - One transaction associated with a XAConnection
532:                if (currentXid != null)
533:                    throw new XAException(XAException.XAER_PROTO);
534:
535:                // ensure immtable and correct equals method.
536:                XAXactId xid_im = new XAXactId(xid);
537:
538:                XATransactionState tranState = getTransactionState(xid_im);
539:
540:                switch (flags) {
541:                case XAResource.TMNOFLAGS:
542:                    if (tranState != null)
543:                        throw new XAException(XAException.XAER_DUPID);
544:
545:                    try {
546:
547:                        if (con.realConnection == null) {
548:                            con.openRealConnection();
549:
550:                            if (con.currentConnectionHandle != null) {
551:
552:                                // since this is a new connection, set its complete
553:                                // state according to the application's Connection
554:                                // handle view of the world.
555:                                con.currentConnectionHandle.setState(true);
556:                                con.realConnection
557:                                        .setApplicationConnection(con.currentConnectionHandle);
558:                            }
559:
560:                        } else {
561:
562:                            // XAResource.start() auto commits in DB2 when in 
563:                            // auto commit mode.
564:                            if (con.currentConnectionHandle != null) {
565:                                if (con.currentConnectionHandle.getAutoCommit())
566:                                    con.currentConnectionHandle.rollback();
567:                            }
568:                            if (!con.realConnection.transactionIsIdle())
569:                                throw new XAException(XAException.XAER_OUTSIDE);
570:
571:                            if (con.currentConnectionHandle != null) {
572:                                // It is possible that the isolation level state 
573:                                // in connection handle has gotten out of sync 
574:                                // with the real isolation level. This can happen 
575:                                // if SLQ instead of JDBC api has been used to set 
576:                                // the isolation level. The code below will check 
577:                                // if isolation was set using JDBC or SQL and if 
578:                                // yes, then it will update the isolation state 
579:                                // in BrokeredConnection with EmbedConnection's
580:                                // isolation level.
581:                                con.currentConnectionHandle
582:                                        .getIsolationUptoDate();
583:                                // we have a current handle so we need to keep
584:                                // the connection state of the current connection.
585:                                con.currentConnectionHandle.setState(true);
586:
587:                                // At the local to global transition we need 
588:                                // to discard and close any open held result 
589:                                // sets, a rollback will do this.
590:                                con.realConnection.rollback();
591:                            } else {
592:                                con.resetRealConnection();
593:                            }
594:
595:                        }
596:
597:                        // Global connections are always in auto commit false mode.
598:                        con.realConnection.setAutoCommit(false);
599:
600:                        // and holdability false (cannot hold cursors across 
601:                        // XA transactions.
602:                        con.realConnection
603:                                .setHoldability(JDBC30Translation.CLOSE_CURSORS_AT_COMMIT);
604:
605:                        con.realConnection.getLanguageConnection()
606:                                .getTransactionExecute()
607:                                .createXATransactionFromLocalTransaction(
608:                                        xid_im.getFormatId(),
609:                                        xid_im.getGlobalTransactionId(),
610:                                        xid_im.getBranchQualifier());
611:
612:                    } catch (StandardException se) {
613:                        throw wrapInXAException(se);
614:                    } catch (SQLException sqle) {
615:                        throw wrapInXAException(sqle);
616:                    }
617:
618:                    if (!ra.addConnection(xid_im, new XATransactionState(
619:                            con.realConnection.getContextManager(),
620:                            con.realConnection, this , xid_im)))
621:                        throw new XAException(XAException.XAER_DUPID);
622:
623:                    break;
624:
625:                case XAResource.TMRESUME:
626:                case XAResource.TMJOIN:
627:                    if (tranState == null)
628:                        throw new XAException(XAException.XAER_NOTA);
629:
630:                    tranState.start(this , flags);
631:
632:                    if (tranState.conn != con.realConnection) {
633:
634:                        if (con.realConnection != null) {
635:
636:                            if (!con.realConnection.transactionIsIdle())
637:                                throw new XAException(XAException.XAER_OUTSIDE);
638:
639:                            // We need to get the isolation level up to date same 
640:                            // way as it is done at start of a transaction. Before
641:                            // joining the transaction, it is possible that the 
642:                            // isolation level was updated using SQL. We need to 
643:                            // get this state and store in the connection handle so 
644:                            // that we can restore the isolation when we are in the 
645:                            // local mode.
646:                            try {
647:                                if (con.currentConnectionHandle != null) {
648:                                    con.currentConnectionHandle
649:                                            .getIsolationUptoDate();
650:                                }
651:                            } catch (SQLException sqle) {
652:                                throw wrapInXAException(sqle);
653:                            }
654:
655:                            closeUnusedConnection(con.realConnection);
656:                        }
657:                        con.realConnection = tranState.conn;
658:
659:                        if (con.currentConnectionHandle != null) {
660:
661:                            try {
662:                                // only reset the non-transaction specific 
663:                                // Connection state.
664:                                con.currentConnectionHandle.setState(false);
665:                                con.realConnection
666:                                        .setApplicationConnection(con.currentConnectionHandle);
667:                            } catch (SQLException sqle) {
668:                                throw wrapInXAException(sqle);
669:                            }
670:                        }
671:
672:                    }
673:
674:                    break;
675:
676:                default:
677:                    throw new XAException(XAException.XAER_INVAL);
678:                }
679:
680:                currentXid = xid_im;
681:            }
682:
683:            /**
684:             * Resturns currently active xid
685:             * @return Xid
686:             */
687:            Xid getCurrentXid() {
688:                return currentXid;
689:            }
690:
691:            /**
692:             * Returns the XATransactionState of the the transaction
693:             * @param xid_im 
694:             * @return XATransactionState
695:             */
696:            private XATransactionState getTransactionState(XAXactId xid_im) {
697:                return (XATransactionState) ra.findConnection(xid_im);
698:            }
699:
700:            /**
701:             * Compares the user name and password of the XAResource with
702:             * user name and password of this and throws XAException if there is 
703:             * a mismatch
704:             * @param original EmbedXAResource
705:             */
706:            private void checkUserCredentials(EmbedXAResource original)
707:                    throws XAException {
708:                if (original == this )
709:                    return;
710:                if (original.con.getPassword().equals(con.getPassword())
711:                        && (original.con.getUsername()
712:                                .equals(con.getUsername())))
713:                    return;
714:                throw new XAException(XAException.XA_RBINTEGRITY);
715:            }
716:
717:            /**
718:             * Checks if currently associated connection is active
719:             * throws exception if not
720:             */
721:            private void checkXAActive() throws XAException {
722:                try {
723:                    con.checkActive();
724:                } catch (SQLException sqle) {
725:                    throw wrapInXAException(sqle);
726:                }
727:            }
728:
729:            /**
730:             * Map a SQL exception to appropriate XAException.
731:             * Return the mapped XAException.
732:             */
733:            private static XAException wrapInXAException(SQLException se) {
734:                // Map interesting exceptions to XAException
735:                String sqlstate = se.getSQLState();
736:                String message = se.getMessage();
737:
738:                XAException xae;
739:
740:                if (sqlstate == null) {
741:                    // no idea what was wrong, throw non-descript error.
742:                    if (message != null)
743:                        xae = new XAException(message);
744:                    else
745:                        xae = new XAException(XAException.XAER_RMERR);
746:                } else if (sqlstate
747:                        .equals(StandardException
748:                                .getSQLStateFromIdentifier(SQLState.STORE_XA_XAER_DUPID)))
749:                    xae = new XAException(XAException.XAER_DUPID);
750:                else if (sqlstate
751:                        .equals(StandardException
752:                                .getSQLStateFromIdentifier(SQLState.STORE_XA_PROTOCOL_VIOLATION)))
753:                    xae = new XAException(XAException.XA_RBPROTO);
754:                else if (sqlstate.equals(SQLState.DEADLOCK))
755:                    xae = new XAException(XAException.XA_RBDEADLOCK);
756:                else if (sqlstate.equals(SQLState.LOCK_TIMEOUT))
757:                    xae = new XAException(XAException.XA_RBTIMEOUT);
758:                else if (message != null)
759:                    xae = new XAException(message);
760:                else
761:                    xae = new XAException(XAException.XAER_RMERR);
762:
763:                if (JVMInfo.JDK_ID >= JVMInfo.J2SE_14)
764:                    xae.initCause(se);
765:                return xae;
766:            }
767:
768:            /**
769:             * Map a Standard exception to appropriate XAException.
770:             * Return the mapped XAException.
771:             */
772:            private static XAException wrapInXAException(StandardException se) {
773:                return wrapInXAException(TransactionResourceImpl
774:                        .wrapInSQLException((SQLException) null, se));
775:            }
776:
777:            /**
778:             * Return an underlying connection object back to its XAResource
779:             * if possible. If not close the connection.
780:             * @param tranState 
781:             * @param xid_im 
782:             */
783:            private void returnConnectionToResource(
784:                    XATransactionState tranState, XAXactId xid_im) {
785:
786:                removeXATransaction(xid_im);
787:                synchronized (tranState) {
788:                    // global transaction is over.
789:                    tranState.associationState = XATransactionState.TC_COMPLETED;
790:                    tranState.notifyAll();
791:
792:                    EmbedConnection conn = tranState.conn;
793:
794:                    // already set in its own resource
795:                    // or can it be returned to its original resource?
796:                    if ((tranState.creatingResource.con.realConnection == conn)
797:                            || (tranState.creatingResource.con.realConnection == null)) {
798:
799:                        tranState.creatingResource.con.realConnection = conn;
800:
801:                        BrokeredConnection handle = tranState.creatingResource.con.currentConnectionHandle;
802:
803:                        conn.setApplicationConnection(handle);
804:
805:                        if (handle != null) {
806:                            try {
807:                                handle.setState(true);
808:                            } catch (SQLException sqle) {
809:
810:                                // couldn't reset the connection
811:                                closeUnusedConnection(tranState.conn);
812:                                tranState.creatingResource.con.realConnection = null;
813:                            }
814:                        }
815:                        return;
816:                    }
817:                }
818:
819:                // nowhere to place it, close it.
820:                closeUnusedConnection(tranState.conn);
821:            }
822:
823:            /**
824:             * Close  an underlying connection object when there is
825:             * no active XAResource to hand it to.
826:             * @param conn 
827:             */
828:            private static void closeUnusedConnection(EmbedConnection conn) {
829:                if (conn != null) {
830:                    try {
831:                        conn.close();
832:                    } catch (SQLException sqle) {
833:
834:                    }
835:                }
836:            }
837:
838:            /**
839:             * Removes the xid from currently active transactions
840:             * @param xid_im 
841:             */
842:            private void removeXATransaction(XAXactId xid_im) {
843:                XATransactionState tranState = (XATransactionState) ra
844:                        .removeConnection(xid_im);
845:                if (tranState != null)
846:                    tranState.popMe();
847:            }
848:
849:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.