1 17 package org.apache.geronimo.transaction.manager; 18 19 import java.util.Collection ; 20 import java.util.HashMap ; 21 import java.util.Iterator ; 22 import java.util.Map ; 23 import javax.resource.spi.XATerminator ; 24 import javax.transaction.InvalidTransactionException ; 25 import javax.transaction.Status ; 26 import javax.transaction.SystemException ; 27 import javax.transaction.Transaction ; 28 import javax.transaction.xa.XAException ; 29 import javax.transaction.xa.XAResource ; 30 import javax.transaction.xa.Xid ; 31 32 35 public class GeronimoTransactionManager extends TransactionManagerImpl implements XATerminator , XAWork { 36 private final Map importedTransactions = new HashMap (); 37 private boolean isInRecovery = false; 38 39 public GeronimoTransactionManager() throws XAException { 40 } 41 42 public GeronimoTransactionManager(int defaultTransactionTimeoutSeconds) throws XAException { 43 super(defaultTransactionTimeoutSeconds); 44 } 45 46 public GeronimoTransactionManager(int defaultTransactionTimeoutSeconds, TransactionLog transactionLog) throws XAException { 47 super(defaultTransactionTimeoutSeconds, transactionLog); 48 } 49 50 public GeronimoTransactionManager(int defaultTransactionTimeoutSeconds, XidFactory xidFactory, TransactionLog transactionLog, Collection resourceManagers) throws XAException { 51 super(defaultTransactionTimeoutSeconds, xidFactory, transactionLog, resourceManagers); 52 } 53 54 57 public void commit(Xid xid, boolean onePhase) throws XAException { 58 Transaction importedTransaction; 59 synchronized (importedTransactions) { 60 importedTransaction = (Transaction ) importedTransactions.remove(xid); 61 } 62 if (importedTransaction == null) { 63 throw new XAException ("No imported transaction for xid: " + xid); 64 } 65 66 try { 67 int status = importedTransaction.getStatus(); 68 assert status == Status.STATUS_ACTIVE || status == Status.STATUS_PREPARED: "invalid status: " + status; 69 } catch (SystemException e) { 70 throw new XAException (); 71 } 72 commit(importedTransaction, onePhase); 73 } 74 75 78 public void forget(Xid xid) throws XAException { 79 Transaction importedTransaction; 80 synchronized (importedTransactions) { 81 importedTransaction = (Transaction ) importedTransactions.remove(xid); 82 } 83 if (importedTransaction == null) { 84 throw new XAException ("No imported transaction for xid: " + xid); 85 } 86 forget(importedTransaction); 94 } 95 96 99 public int prepare(Xid xid) throws XAException { 100 Transaction importedTransaction; 101 synchronized (importedTransactions) { 102 importedTransaction = (Transaction ) importedTransactions.get(xid); 103 } 104 if (importedTransaction == null) { 105 throw new XAException ("No imported transaction for xid: " + xid); 106 } 107 try { 108 int status = importedTransaction.getStatus(); 109 assert status == Status.STATUS_ACTIVE; 110 } catch (SystemException e) { 111 throw new XAException (); 112 } 113 return prepare(importedTransaction); 114 } 115 116 119 public Xid [] recover(int flag) throws XAException { 120 if (!isInRecovery) { 121 if ((flag & XAResource.TMSTARTRSCAN) == 0) { 122 throw new XAException (XAException.XAER_PROTO); 123 } 124 isInRecovery = true; 125 } 126 if ((flag & XAResource.TMENDRSCAN) != 0) { 127 isInRecovery = false; 128 } 129 if ((flag & XAResource.TMSTARTRSCAN) != 0) { 132 Map recoveredXidMap = getExternalXids(); 133 Xid [] recoveredXids = new Xid [recoveredXidMap.size()]; 134 int i = 0; 135 synchronized (importedTransactions) { 136 for (Iterator iterator = recoveredXidMap.entrySet().iterator(); iterator.hasNext();) { 137 Map.Entry entry = (Map.Entry ) iterator.next(); 138 Xid xid = (Xid ) entry.getKey(); 139 recoveredXids[i++] = xid; 140 Transaction transaction = (Transaction ) entry.getValue(); 141 importedTransactions.put(xid, transaction); 142 } 143 } 144 return recoveredXids; 145 } else { 146 return new Xid [0]; 147 } 148 } 149 150 153 public void rollback(Xid xid) throws XAException { 154 Transaction importedTransaction; 155 synchronized (importedTransactions) { 156 importedTransaction = (Transaction ) importedTransactions.remove(xid); 157 } 158 if (importedTransaction == null) { 159 throw new XAException ("No imported transaction for xid: " + xid); 160 } 161 try { 162 int status = importedTransaction.getStatus(); 163 assert status == Status.STATUS_ACTIVE || status == Status.STATUS_PREPARED; 164 } catch (SystemException e) { 165 throw new XAException (); 166 } 167 rollback(importedTransaction); 168 } 169 170 171 public void begin(Xid xid, long txTimeoutMillis) throws XAException , InvalidTransactionException , SystemException , ImportedTransactionActiveException { 173 Transaction importedTransaction; 174 synchronized (importedTransactions) { 175 importedTransaction = (Transaction ) importedTransactions.get(xid); 176 if (importedTransaction == null) { 177 importedTransaction = importXid(xid, txTimeoutMillis); 179 importedTransactions.put(xid, importedTransaction); 180 } 181 try { 183 resume(importedTransaction); 184 } catch (InvalidTransactionException e) { 185 throw new ImportedTransactionActiveException(xid); 187 } 188 } 189 } 190 191 public void end(Xid xid) throws XAException , SystemException { 192 synchronized (importedTransactions) { 193 Transaction importedTransaction = (Transaction ) importedTransactions.get(xid); 194 if (importedTransaction == null) { 195 throw new XAException ("No imported transaction for xid: " + xid); 196 } 197 if (importedTransaction != getTransaction()) { 198 throw new XAException ("Imported transaction is not associated with the curren thread xid: " + xid); 199 } 200 suspend(); 201 } 202 } 203 } 204 | Popular Tags |