1 22 package org.jboss.test.tm.resource; 23 24 import java.io.Serializable ; 25 import java.util.Collections ; 26 import java.util.HashMap ; 27 import java.util.Map ; 28 29 import javax.naming.InitialContext ; 30 import javax.transaction.Synchronization ; 31 import javax.transaction.Transaction ; 32 import javax.transaction.TransactionManager ; 33 34 import org.jboss.logging.Logger; 35 import org.jboss.tm.TxUtils; 36 37 45 public class MTOperation implements Serializable 46 { 47 49 50 private static final long serialVersionUID = 2924873545494045020L; 51 52 public static final int TM_GET_STATUS = 0; 53 public static final int TM_BEGIN = 1; 54 public static final int TM_RESUME = 2; 55 public static final int TM_COMMIT = 3; 56 public static final int TX_COMMIT = 4; 57 public static final int TX_REGISTER_SYNC = 5; 58 public static final int XX_SLEEP_200 = 6; 59 public static final int XX_WAIT_FOR = 7; 60 61 62 protected static Logger log; 63 64 65 protected static TransactionManager tm = null; 66 67 68 protected static Map resources = Collections.synchronizedMap(new HashMap ()); 69 70 71 protected static Map transactions = Collections.synchronizedMap(new HashMap ()); 72 73 75 76 protected Integer id; 77 78 79 protected int op; 80 81 82 protected Throwable throwable; 83 84 86 89 public static void init(Logger log) throws Exception 90 { 91 MTOperation.log = log; 92 93 if (getTM().getTransaction() != null) 94 { 95 throw new IllegalStateException ("Invalid thread association " + getTM().getTransaction()); 96 } 97 resources.clear(); 98 transactions.clear(); 99 } 100 101 104 public static TransactionManager getTM() throws Exception 105 { 106 if (tm == null) 107 { 108 tm = (TransactionManager ) new InitialContext ().lookup("java:/TransactionManager"); 109 } 110 return tm; 111 } 112 113 116 public static void destroy() 117 { 118 resources.clear(); 119 transactions.clear(); 120 } 121 122 124 public MTOperation(int op) 125 { 126 this(op, 0); 127 } 128 129 public MTOperation(int op, int id) 130 { 131 this.id = new Integer (id); 132 this.op = op; 133 } 134 135 public MTOperation(int op, int id, Throwable throwable) 136 { 137 this.id = new Integer (id); 138 this.op = op; 139 this.throwable = throwable; 140 } 141 142 144 public void perform() throws Exception 145 { 146 Throwable caught = null; 147 try 148 { 149 switch (op) 150 { 151 case TM_GET_STATUS: 152 tmGetStatus(); 153 break; 154 155 case TM_BEGIN: 156 tmBegin(); 157 break; 158 159 case TM_RESUME: 160 tmResume(); 161 break; 162 163 case TM_COMMIT: 164 tmCommit(); 165 break; 166 167 case TX_COMMIT: 168 txCommit(); 169 break; 170 171 case TX_REGISTER_SYNC: 172 txRegisterSync(); 173 break; 174 175 case XX_SLEEP_200: 176 xxSleep200(); 177 break; 178 179 case XX_WAIT_FOR: 180 xxWaitForTx(); 181 break; 182 183 default: 184 throw new IllegalArgumentException ("Invalid operation " + op); 185 } 186 } 187 catch (Throwable t) 188 { 189 caught = t; 190 } 191 192 if (throwable != null && caught == null) 194 { 195 throw new Exception ("Expected throwable " + throwable); 196 } 197 198 if (throwable != null && (throwable.getClass().isAssignableFrom(caught.getClass())) == false) 200 { 201 log.warn("Caught wrong throwable", caught); 202 throw new Exception ("Expected throwable " + throwable + " caught " + caught); 203 } 204 205 if (throwable == null && caught != null) 207 { 208 log.warn("Caught unexpected throwable", caught); 209 throw new Exception ("Unexpected throwable " + caught); 210 } 211 } 212 213 public void tmGetStatus() throws Exception 214 { 215 log.info(tid() + " " + TxUtils.getStatusAsString(getTM().getStatus())); 216 } 217 218 public void tmBegin() throws Exception 219 { 220 log.info(tid() + " TM_BEGIN (" + id + ")"); 221 getTM().begin(); 222 Transaction tx = getTM().getTransaction(); 223 synchronized (transactions) 224 { 225 transactions.put(id, tx); 226 transactions.notifyAll(); 227 } 228 } 229 230 public void tmResume() throws Exception 231 { 232 log.info(tid() + " TM_RESUME (" + id + ")"); 233 Transaction tx = (Transaction )transactions.get(id); 234 if (tx == null) 235 { 236 throw new IllegalStateException ("Tx not found:" + id); 237 } 238 else 239 { 240 getTM().resume(tx); 241 } 242 } 243 244 public void tmCommit() throws Exception 245 { 246 log.info(tid() + " TM_COMMIT"); 247 getTM().commit(); 248 } 249 250 public void txCommit() throws Exception 251 { 252 log.info(tid() + " TX_COMMIT (" + id + ")"); 253 Transaction tx = (Transaction )transactions.get(id); 254 if (tx == null) 255 { 256 throw new IllegalStateException ("Tx not found: " + id); 257 } 258 else 259 { 260 tx.commit(); 261 } 262 } 263 264 public void txRegisterSync() throws Exception 265 { 266 log.info(tid() + " TX_REGISTER_SYNC (" + id + ")"); 267 Transaction tx = (Transaction )transactions.get(id); 268 if (tx == null) 269 { 270 throw new IllegalStateException ("Tx not found: " + id); 271 } 272 Synchronization sync = new Synchronization () 273 { 274 public void beforeCompletion() 275 { 276 log.info(tid() + " beforeCompletion() called"); 277 } 278 279 public void afterCompletion(int status) 280 { 281 log.info (tid() + " afterCompletion(" + TxUtils.getStatusAsString(status) + ") called"); 282 } 283 }; 284 tx.registerSynchronization(sync); 285 } 286 287 public void xxWaitForTx() throws Exception 288 { 289 log.info(tid() + " XX_WAIT_FOR (" + id + ")"); 290 291 Transaction tx = (Transaction )transactions.get(id); 292 while (tx == null) 293 { 294 log.info(tid() + " Sleeping for 100 msecs"); 295 synchronized (transactions) 296 { 297 try 298 { 299 transactions.wait(100); 300 } 301 catch (InterruptedException ignore) {} 302 } 303 tx = (Transaction )transactions.get(id); 304 } 305 log.info(tid() + " Got it"); 306 } 307 308 public void xxSleep200() throws Exception 309 { 310 log.info(tid() + " XX_SLEEP_200"); 311 Thread.sleep(200); 312 } 313 314 private String tid() 315 { 316 return Thread.currentThread().getName(); 317 } 318 } 319 | Popular Tags |