1 18 package org.apache.activemq.transaction; 19 20 import java.io.IOException ; 21 22 import javax.transaction.xa.XAException ; 23 import javax.transaction.xa.XAResource ; 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 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 , IOException { 50 if(log.isDebugEnabled()) 51 log.debug("XA Transaction commit: "+xid); 52 53 switch (getState()) { 54 case START_STATE: 55 checkForPreparedState(onePhase); 57 setStateFinished(); 58 break; 59 case IN_USE_STATE: 60 checkForPreparedState(onePhase); 62 doPrePrepare(); 63 setStateFinished(); 64 transactionStore.commit(getTransactionId(), false); 65 doPostCommit(); 66 break; 67 case PREPARED_STATE: 68 setStateFinished(); 71 transactionStore.commit(getTransactionId(), true); 72 doPostCommit(); 73 break; 74 default: 75 illegalStateTransition("commit"); 76 } 77 } 78 79 private void illegalStateTransition(String callName) throws XAException { 80 XAException xae = new XAException ("Cannot call " + callName + " now."); 81 xae.errorCode = XAException.XAER_PROTO; 82 throw xae; 83 } 84 85 private void checkForPreparedState(boolean onePhase) throws XAException { 86 if (!onePhase) { 87 XAException xae = new XAException ("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 , IOException { 94 try { 95 prePrepare(); 96 } catch (XAException e) { 97 throw e; 98 } catch (Throwable e) { 99 log.warn("PRE-PREPARE FAILED: ", e); 100 rollback(); 101 XAException xae = new XAException ("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 { 109 try { 110 fireAfterCommit(); 111 } 112 catch (Throwable e) { 113 log.warn("POST COMMIT FAILED: ", e); 116 XAException xae = new XAException ("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 , IOException { 124 125 if(log.isDebugEnabled()) 126 log.debug("XA Transaction rollback: "+xid); 127 128 switch (getState()) { 129 case START_STATE: 130 setStateFinished(); 132 break; 133 case IN_USE_STATE: 134 setStateFinished(); 136 transactionStore.rollback(getTransactionId()); 137 doPostRollback(); 138 break; 139 case PREPARED_STATE: 140 setStateFinished(); 142 transactionStore.rollback(getTransactionId()); 143 doPostRollback(); 144 break; 145 } 146 147 } 148 149 private void doPostRollback() throws XAException { 150 try { 151 fireAfterRollback(); 152 } 153 catch (Throwable e) { 154 log.warn("POST ROLLBACK FAILED: ", e); 157 XAException xae = new XAException ("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 , IOException { 165 if(log.isDebugEnabled()) 166 log.debug("XA Transaction prepare: "+xid); 167 168 switch (getState()) { 169 case START_STATE: 170 setStateFinished(); 172 return XAResource.XA_RDONLY; 173 case IN_USE_STATE: 174 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 |