EMMA Coverage Report (generated Wed Jun 28 22:15:27 PDT 2006)
[all classes][org.apache.derby.jdbc]

COVERAGE SUMMARY FOR SOURCE FILE [XATransactionState.java]

nameclass, %method, %block, %line, %
XATransactionState.java100% (1/1)100% (4/4)84%  (303/360)85%  (85.4/101)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class XATransactionState100% (1/1)100% (4/4)84%  (303/360)85%  (85.4/101)
XATransactionState (ContextManager, EmbedConnection, EmbedXAConnection, XAXac... 100% (1/1)100% (20/20)100% (7/7)
cleanupOnError (Throwable): void 100% (1/1)77%  (41/53)81%  (11.4/14)
end (EmbedXAConnection, int, boolean): boolean 100% (1/1)87%  (161/186)87%  (47/54)
start (EmbedXAConnection, int): void 100% (1/1)80%  (81/101)77%  (20/26)

1/*
2 
3   Derby - Class org.apache.derby.jdbc.XATransactionState
4 
5   Copyright 2003, 2005 The Apache Software Foundation or its licensors, as applicable.
6 
7   Licensed under the Apache License, Version 2.0 (the "License");
8   you may not use this file except in compliance with the License.
9   You may obtain a copy of the License at
10 
11      http://www.apache.org/licenses/LICENSE-2.0
12 
13   Unless required by applicable law or agreed to in writing, software
14   distributed under the License is distributed on an "AS IS" BASIS,
15   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   See the License for the specific language governing permissions and
17   limitations under the License.
18 
19 */
20 
21package org.apache.derby.jdbc;
22 
23 
24import org.apache.derby.impl.jdbc.EmbedConnection;
25import javax.transaction.xa.XAResource;
26import org.apache.derby.iapi.services.context.ContextImpl;
27import org.apache.derby.iapi.services.context.ContextManager;
28import org.apache.derby.iapi.error.ExceptionSeverity;
29import org.apache.derby.iapi.error.StandardException;
30import org.apache.derby.iapi.store.access.xa.XAXactId;
31import org.apache.derby.iapi.reference.SQLState;
32import java.util.HashMap;
33import javax.transaction.xa.XAException;
34 
35/** 
36*/
37final class XATransactionState extends ContextImpl {
38 
39        /** Rollback-only due to deadlock */
40        final static int TRO_DEADLOCK                                = -2;
41        /** Rollback-only due to end(TMFAIL) */
42        final static int TRO_FAIL                                        = -1;
43        final static int T0_NOT_ASSOCIATED                        = 0;
44        final static int T1_ASSOCIATED                                = 1;
45        // final static int T2_ASSOCIATION_SUSPENDED        = 2;
46        final static int TC_COMPLETED                                = 3; // rollback/commit called
47 
48        final EmbedConnection        conn;
49        final EmbedXAResource creatingResource;
50        // owning XAResource
51        private EmbedXAResource  associatedResource;        
52        final XAXactId                        xid;        
53        /**
54                When an XAResource suspends a transaction (end(TMSUSPEND)) it must be resumed
55                using the same XAConnection. This has been the traditional Cloudscape behaviour,
56                though there does not seem to be a specific reference to this behaviour in
57                the JTA spec. Note that while the transaction is suspended by this XAResource,
58                another XAResource may join the transaction and suspend it after the join.
59        */
60        HashMap suspendedList;
61 
62 
63        /**
64                Association state of the transaction.
65        */
66        int associationState;
67 
68        int rollbackOnlyCode;
69 
70 
71        /**
72                has this transaction been prepared.
73        */
74        boolean isPrepared;
75 
76        XATransactionState(ContextManager cm, EmbedConnection conn, 
77                EmbedXAResource resource, XAXactId xid) {
78 
79                super(cm, "XATransactionState");
80                this.conn = conn;
81                this.associatedResource = resource;
82                this.creatingResource = resource;
83                this.associationState = XATransactionState.T1_ASSOCIATED;
84                this.xid = xid;
85 
86        }
87 
88        public void cleanupOnError(Throwable t) {
89 
90                if (t instanceof StandardException) {
91 
92                        StandardException se = (StandardException) t;
93            
94            if (se.getSeverity() >= ExceptionSeverity.SESSION_SEVERITY) {
95                popMe();
96                return;
97            }
98 
99                        if (se.getSeverity() == ExceptionSeverity.TRANSACTION_SEVERITY) {
100 
101                                synchronized (this) {
102                                        // disable use of the connection until it is cleaned up.
103                                        conn.setApplicationConnection(null);
104                                        notifyAll();
105                                        associationState = TRO_FAIL;
106                                        if (SQLState.DEADLOCK.equals(se.getMessageId()))
107                                                rollbackOnlyCode = XAException.XA_RBDEADLOCK;
108                                        else if (SQLState.LOCK_TIMEOUT.equals(se.getMessageId()))
109                                                rollbackOnlyCode = XAException.XA_RBTIMEOUT;                                        
110                                        else
111                                                rollbackOnlyCode = XAException.XA_RBOTHER;
112                                }
113                        }
114                }
115        }
116 
117        void start(EmbedXAResource resource, int flags) throws XAException {
118 
119                synchronized (this) {
120                        if (associationState == XATransactionState.TRO_FAIL)
121                                throw new XAException(rollbackOnlyCode);
122 
123                        boolean isSuspendedByResource = (suspendedList != null) && (suspendedList.get(resource) != null);
124 
125                        if (flags == XAResource.TMRESUME) {
126                                if (!isSuspendedByResource)
127                                        throw new XAException(XAException.XAER_PROTO);
128 
129                        } else {
130                                // cannot join a transaction we have suspended.
131                                if (isSuspendedByResource)
132                                        throw new XAException(XAException.XAER_PROTO);
133                        }
134 
135                        while (associationState == XATransactionState.T1_ASSOCIATED) {
136                                
137                                try {
138                                        wait();
139                                } catch (InterruptedException ie) {
140                                        throw new XAException(XAException.XA_RETRY);
141                                }
142                        }
143 
144 
145                        switch (associationState) {
146                        case XATransactionState.T0_NOT_ASSOCIATED:
147                                break;
148 
149                        case XATransactionState.TRO_FAIL:
150                                throw new XAException(rollbackOnlyCode);
151 
152                        default:
153                                throw new XAException(XAException.XAER_NOTA);
154                        }
155 
156                        if (isPrepared)
157                                throw new XAException(XAException.XAER_PROTO);
158 
159                        if (isSuspendedByResource) {
160                                suspendedList.remove(resource);
161                        }
162 
163                        associationState = XATransactionState.T1_ASSOCIATED;
164                        associatedResource = resource;
165                }
166        }
167 
168        boolean end(EmbedXAResource resource, int flags, 
169                boolean endingCurrentXid) throws XAException {
170 
171                boolean rollbackOnly = false;
172                synchronized (this) {
173 
174 
175                        boolean isSuspendedByResource = (suspendedList != null) && (suspendedList.get(resource) != null);
176 
177                        if (!endingCurrentXid) {
178                                while (associationState == XATransactionState.T1_ASSOCIATED) {
179                                        
180                                        try {
181                                                wait();
182                                        } catch (InterruptedException ie) {
183                                                throw new XAException(XAException.XA_RETRY);
184                                        }
185                                }
186                        }
187 
188                        switch (associationState) {
189                        case XATransactionState.TC_COMPLETED:
190                                throw new XAException(XAException.XAER_NOTA);
191                        case XATransactionState.TRO_FAIL:
192                                if (endingCurrentXid)
193                                        flags = XAResource.TMFAIL;
194                                else
195                                        throw new XAException(rollbackOnlyCode);
196                        }
197 
198                        boolean notify = false;
199                        switch (flags) {
200                        case XAResource.TMSUCCESS:
201                                if (isSuspendedByResource) {
202                                        suspendedList.remove(resource);
203                                }
204                                else {
205                                        if (resource != associatedResource)
206                                                throw new XAException(XAException.XAER_PROTO);
207 
208                                        associationState = XATransactionState.T0_NOT_ASSOCIATED;
209                                        associatedResource = null;
210                                        notify = true;
211                                }
212 
213                                conn.setApplicationConnection(null);
214                                break;
215 
216                        case XAResource.TMFAIL:
217 
218                                if (isSuspendedByResource) {
219                                        suspendedList.remove(resource);
220                                } else {
221                                        if (resource != associatedResource)
222                                                throw new XAException(XAException.XAER_PROTO);
223                                        associatedResource = null;
224                                }
225                                
226                                if (associationState != XATransactionState.TRO_FAIL) {
227                                        associationState = XATransactionState.TRO_FAIL;
228                                        rollbackOnlyCode = XAException.XA_RBROLLBACK;
229                                }
230                                conn.setApplicationConnection(null);
231                                notify = true;
232                                rollbackOnly = true;
233                                break;
234 
235                        case XAResource.TMSUSPEND:
236                                if (isSuspendedByResource)
237                                        throw new XAException(XAException.XAER_PROTO);
238                                
239                                if (resource != associatedResource)
240                                        throw new XAException(XAException.XAER_PROTO);
241 
242                                if (suspendedList == null)
243                                        suspendedList = new HashMap();
244                                suspendedList.put(resource, this);
245 
246                                associationState = XATransactionState.T0_NOT_ASSOCIATED;
247                                associatedResource = null;
248                                conn.setApplicationConnection(null);
249                                notify = true;
250 
251                                break;
252 
253                        default:
254                                throw new XAException(XAException.XAER_INVAL);
255                        }
256 
257                        if (notify)
258                                notifyAll();
259 
260                        return rollbackOnly;
261                }
262        }
263 
264}

[all classes][org.apache.derby.jdbc]
EMMA 2.0.5312 (C) Vladimir Roubtsov