KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > activemq > transaction > XATransaction


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

18 package org.apache.activemq.transaction;
19
20 import java.io.IOException JavaDoc;
21
22 import javax.transaction.xa.XAException JavaDoc;
23 import javax.transaction.xa.XAResource JavaDoc;
24
25 import org.apache.activemq.broker.TransactionBroker;
26 import org.apache.activemq.command.TransactionId;
27 import org.apache.activemq.command.XATransactionId;
28 import org.apache.activemq.store.TransactionStore;
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31
32 /**
33  * @version $Revision: 1.4 $
34  */

35 public class XATransaction extends Transaction {
36     
37     private static final Log log = LogFactory.getLog(XATransaction.class);
38     
39     private final TransactionStore transactionStore;
40     private final XATransactionId xid;
41     private final TransactionBroker broker;
42
43     public XATransaction(TransactionStore transactionStore, XATransactionId xid, TransactionBroker broker) {
44         this.transactionStore = transactionStore;
45         this.xid = xid;
46         this.broker = broker;
47     }
48
49     public void commit(boolean onePhase) throws XAException JavaDoc, IOException JavaDoc {
50         if(log.isDebugEnabled())
51             log.debug("XA Transaction commit: "+xid);
52
53         switch (getState()) {
54             case START_STATE:
55                 // 1 phase commit, no work done.
56
checkForPreparedState(onePhase);
57                 setStateFinished();
58                 break;
59             case IN_USE_STATE:
60                 // 1 phase commit, work done.
61
checkForPreparedState(onePhase);
62                 doPrePrepare();
63                 setStateFinished();
64                 transactionStore.commit(getTransactionId(), false);
65                 doPostCommit();
66                 break;
67             case PREPARED_STATE:
68                 // 2 phase commit, work done.
69
// We would record commit here.
70
setStateFinished();
71                 transactionStore.commit(getTransactionId(), true);
72                 doPostCommit();
73                 break;
74             default:
75                 illegalStateTransition("commit");
76         }
77     }
78
79     private void illegalStateTransition(String JavaDoc callName) throws XAException JavaDoc {
80         XAException JavaDoc xae = new XAException JavaDoc("Cannot call " + callName + " now.");
81         xae.errorCode = XAException.XAER_PROTO;
82         throw xae;
83     }
84
85     private void checkForPreparedState(boolean onePhase) throws XAException JavaDoc {
86         if (!onePhase) {
87             XAException JavaDoc xae = new XAException JavaDoc("Cannot do 2 phase commit if the transaction has not been prepared.");
88             xae.errorCode = XAException.XAER_PROTO;
89             throw xae;
90         }
91     }
92
93     private void doPrePrepare() throws XAException JavaDoc, IOException JavaDoc {
94         try {
95             prePrepare();
96         } catch (XAException JavaDoc e) {
97             throw e;
98         } catch (Throwable JavaDoc e) {
99             log.warn("PRE-PREPARE FAILED: ", e);
100             rollback();
101             XAException JavaDoc xae = new XAException JavaDoc("PRE-PREPARE FAILED: Transaction rolled back.");
102             xae.errorCode = XAException.XA_RBOTHER;
103             xae.initCause(e);
104             throw xae;
105         }
106     }
107
108     private void doPostCommit() throws XAException JavaDoc {
109         try {
110             fireAfterCommit();
111         }
112         catch (Throwable JavaDoc e) {
113             // I guess this could happen. Post commit task failed
114
// to execute properly.
115
log.warn("POST COMMIT FAILED: ", e);
116             XAException JavaDoc xae = new XAException JavaDoc("POST COMMIT FAILED");
117             xae.errorCode = XAException.XAER_RMERR;
118             xae.initCause(e);
119             throw xae;
120         }
121     }
122
123     public void rollback() throws XAException JavaDoc, IOException JavaDoc {
124         
125         if(log.isDebugEnabled())
126             log.debug("XA Transaction rollback: "+xid);
127
128         switch (getState()) {
129             case START_STATE:
130                 // 1 phase rollback no work done.
131
setStateFinished();
132                 break;
133             case IN_USE_STATE:
134                 // 1 phase rollback work done.
135
setStateFinished();
136                 transactionStore.rollback(getTransactionId());
137                 doPostRollback();
138                 break;
139             case PREPARED_STATE:
140                 // 2 phase rollback work done.
141
setStateFinished();
142                 transactionStore.rollback(getTransactionId());
143                 doPostRollback();
144                 break;
145         }
146
147     }
148
149     private void doPostRollback() throws XAException JavaDoc {
150         try {
151             fireAfterRollback();
152         }
153         catch (Throwable JavaDoc e) {
154             // I guess this could happen. Post commit task failed
155
// to execute properly.
156
log.warn("POST ROLLBACK FAILED: ", e);
157             XAException JavaDoc xae = new XAException JavaDoc("POST ROLLBACK FAILED");
158             xae.errorCode = XAException.XAER_RMERR;
159             xae.initCause(e);
160             throw xae;
161         }
162     }
163
164     public int prepare() throws XAException JavaDoc, IOException JavaDoc {
165         if(log.isDebugEnabled())
166             log.debug("XA Transaction prepare: "+xid);
167         
168         switch (getState()) {
169             case START_STATE:
170                 // No work done.. no commit/rollback needed.
171
setStateFinished();
172                 return XAResource.XA_RDONLY;
173             case IN_USE_STATE:
174                 // We would record prepare here.
175
doPrePrepare();
176                 setState(Transaction.PREPARED_STATE);
177                 transactionStore.prepare(getTransactionId());
178                 return XAResource.XA_OK;
179             default :
180                 illegalStateTransition("prepare");
181                 return XAResource.XA_RDONLY;
182         }
183     }
184
185     private void setStateFinished() {
186         setState(Transaction.FINISHED_STATE);
187         broker.removeTransaction(xid);
188     }
189
190     public TransactionId getTransactionId() {
191         return xid;
192     }
193 }
194
Popular Tags