KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > jdbc > XATransactionState


1 /*
2
3    Derby - Class org.apache.derby.jdbc.XATransactionState
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to You under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.jdbc;
23
24
25 import org.apache.derby.impl.jdbc.EmbedConnection;
26 import javax.transaction.xa.XAResource JavaDoc;
27 import org.apache.derby.iapi.services.context.ContextImpl;
28 import org.apache.derby.iapi.services.context.ContextManager;
29 import org.apache.derby.iapi.error.ExceptionSeverity;
30 import org.apache.derby.iapi.error.StandardException;
31 import org.apache.derby.iapi.store.access.xa.XAXactId;
32 import org.apache.derby.iapi.reference.SQLState;
33 import java.util.HashMap JavaDoc;
34 import javax.transaction.xa.XAException JavaDoc;
35
36 /**
37 */

38 final class XATransactionState extends ContextImpl {
39
40     /** Rollback-only due to deadlock */
41     final static int TRO_DEADLOCK = -2;
42     /** Rollback-only due to end(TMFAIL) */
43     final static int TRO_FAIL = -1;
44     final static int T0_NOT_ASSOCIATED = 0;
45     final static int T1_ASSOCIATED = 1;
46     // final static int T2_ASSOCIATION_SUSPENDED = 2;
47
final static int TC_COMPLETED = 3; // rollback/commit called
48

49     final EmbedConnection conn;
50     final EmbedXAResource creatingResource;
51         // owning XAResource
52
private EmbedXAResource associatedResource;
53     final XAXactId xid;
54     /**
55         When an XAResource suspends a transaction (end(TMSUSPEND)) it must be resumed
56         using the same XAConnection. This has been the traditional Cloudscape behaviour,
57         though there does not seem to be a specific reference to this behaviour in
58         the JTA spec. Note that while the transaction is suspended by this XAResource,
59         another XAResource may join the transaction and suspend it after the join.
60     */

61     HashMap JavaDoc suspendedList;
62
63
64     /**
65         Association state of the transaction.
66     */

67     int associationState;
68
69     int rollbackOnlyCode;
70
71
72     /**
73         has this transaction been prepared.
74     */

75     boolean isPrepared;
76
77     XATransactionState(ContextManager cm, EmbedConnection conn,
78                 EmbedXAResource resource, XAXactId xid) {
79
80         super(cm, "XATransactionState");
81         this.conn = conn;
82         this.associatedResource = resource;
83         this.creatingResource = resource;
84         this.associationState = XATransactionState.T1_ASSOCIATED;
85         this.xid = xid;
86
87     }
88
89     public void cleanupOnError(Throwable JavaDoc t) {
90
91         if (t instanceof StandardException) {
92
93             StandardException se = (StandardException) t;
94             
95             if (se.getSeverity() >= ExceptionSeverity.SESSION_SEVERITY) {
96                 popMe();
97                 return;
98             }
99
100             if (se.getSeverity() == ExceptionSeverity.TRANSACTION_SEVERITY) {
101
102                 synchronized (this) {
103                     // disable use of the connection until it is cleaned up.
104
conn.setApplicationConnection(null);
105                     notifyAll();
106                     associationState = TRO_FAIL;
107                     if (SQLState.DEADLOCK.equals(se.getMessageId()))
108                         rollbackOnlyCode = XAException.XA_RBDEADLOCK;
109                     else if (SQLState.LOCK_TIMEOUT.equals(se.getMessageId()))
110                         rollbackOnlyCode = XAException.XA_RBTIMEOUT;
111                     else
112                         rollbackOnlyCode = XAException.XA_RBOTHER;
113                 }
114             }
115         }
116     }
117
118     void start(EmbedXAResource resource, int flags) throws XAException JavaDoc {
119
120         synchronized (this) {
121             if (associationState == XATransactionState.TRO_FAIL)
122                 throw new XAException JavaDoc(rollbackOnlyCode);
123
124             boolean isSuspendedByResource = (suspendedList != null) && (suspendedList.get(resource) != null);
125
126             if (flags == XAResource.TMRESUME) {
127                 if (!isSuspendedByResource)
128                     throw new XAException JavaDoc(XAException.XAER_PROTO);
129
130             } else {
131                 // cannot join a transaction we have suspended.
132
if (isSuspendedByResource)
133                     throw new XAException JavaDoc(XAException.XAER_PROTO);
134             }
135
136             while (associationState == XATransactionState.T1_ASSOCIATED) {
137                 
138                 try {
139                     wait();
140                 } catch (InterruptedException JavaDoc ie) {
141                     throw new XAException JavaDoc(XAException.XA_RETRY);
142                 }
143             }
144
145
146             switch (associationState) {
147             case XATransactionState.T0_NOT_ASSOCIATED:
148                 break;
149
150             case XATransactionState.TRO_FAIL:
151                 throw new XAException JavaDoc(rollbackOnlyCode);
152
153             default:
154                 throw new XAException JavaDoc(XAException.XAER_NOTA);
155             }
156
157             if (isPrepared)
158                 throw new XAException JavaDoc(XAException.XAER_PROTO);
159
160             if (isSuspendedByResource) {
161                 suspendedList.remove(resource);
162             }
163
164             associationState = XATransactionState.T1_ASSOCIATED;
165             associatedResource = resource;
166         }
167     }
168
169     boolean end(EmbedXAResource resource, int flags,
170                 boolean endingCurrentXid) throws XAException JavaDoc {
171
172         boolean rollbackOnly = false;
173         synchronized (this) {
174
175
176             boolean isSuspendedByResource = (suspendedList != null) && (suspendedList.get(resource) != null);
177
178             if (!endingCurrentXid) {
179                 while (associationState == XATransactionState.T1_ASSOCIATED) {
180                     
181                     try {
182                         wait();
183                     } catch (InterruptedException JavaDoc ie) {
184                         throw new XAException JavaDoc(XAException.XA_RETRY);
185                     }
186                 }
187             }
188
189             switch (associationState) {
190             case XATransactionState.TC_COMPLETED:
191                 throw new XAException JavaDoc(XAException.XAER_NOTA);
192             case XATransactionState.TRO_FAIL:
193                 if (endingCurrentXid)
194                     flags = XAResource.TMFAIL;
195                 else
196                     throw new XAException JavaDoc(rollbackOnlyCode);
197             }
198
199             boolean notify = false;
200             switch (flags) {
201             case XAResource.TMSUCCESS:
202                 if (isSuspendedByResource) {
203                     suspendedList.remove(resource);
204                 }
205                 else {
206                     if (resource != associatedResource)
207                         throw new XAException JavaDoc(XAException.XAER_PROTO);
208
209                     associationState = XATransactionState.T0_NOT_ASSOCIATED;
210                     associatedResource = null;
211                     notify = true;
212                 }
213
214                 conn.setApplicationConnection(null);
215                 break;
216
217             case XAResource.TMFAIL:
218
219                 if (isSuspendedByResource) {
220                     suspendedList.remove(resource);
221                 } else {
222                     if (resource != associatedResource)
223                         throw new XAException JavaDoc(XAException.XAER_PROTO);
224                     associatedResource = null;
225                 }
226                 
227                 if (associationState != XATransactionState.TRO_FAIL) {
228                     associationState = XATransactionState.TRO_FAIL;
229                     rollbackOnlyCode = XAException.XA_RBROLLBACK;
230                 }
231                 conn.setApplicationConnection(null);
232                 notify = true;
233                 rollbackOnly = true;
234                 break;
235
236             case XAResource.TMSUSPEND:
237                 if (isSuspendedByResource)
238                     throw new XAException JavaDoc(XAException.XAER_PROTO);
239                 
240                 if (resource != associatedResource)
241                     throw new XAException JavaDoc(XAException.XAER_PROTO);
242
243                 if (suspendedList == null)
244                     suspendedList = new HashMap JavaDoc();
245                 suspendedList.put(resource, this);
246
247                 associationState = XATransactionState.T0_NOT_ASSOCIATED;
248                 associatedResource = null;
249                 conn.setApplicationConnection(null);
250                 notify = true;
251
252                 break;
253
254             default:
255                 throw new XAException JavaDoc(XAException.XAER_INVAL);
256             }
257
258             if (notify)
259                 notifyAll();
260
261             return rollbackOnly;
262         }
263     }
264
265 }
266
Popular Tags