1 8 9 package com.sleepycat.je.recovery; 10 11 import java.io.IOException ; 12 import java.util.Hashtable ; 13 14 import javax.transaction.xa.XAException ; 15 import javax.transaction.xa.XAResource ; 16 import javax.transaction.xa.Xid ; 17 18 import junit.framework.Test; 19 import junit.framework.TestSuite; 20 21 import com.sleepycat.je.DatabaseException; 22 import com.sleepycat.je.Transaction; 23 import com.sleepycat.je.XAEnvironment; 24 import com.sleepycat.je.log.LogUtils.XidImpl; 25 26 public class Recovery2PCTest extends RecoveryTestBase { 27 private static final boolean DEBUG = false; 28 29 private boolean explicitTxn; 30 private boolean commit; 31 private boolean recover; 32 33 public static Test suite() { 34 TestSuite allTests = new TestSuite(); 35 for (int i = 0; i < 2; i++) { 36 for (int j = 0; j < 2; j++) { 37 for (int k = 0; k < 2; k++) { 38 allTests.addTest 39 (((Recovery2PCTest) 40 (TestSuite.createTest(Recovery2PCTest.class, 41 "testBasic"))). 42 init(i, j, k)); 43 } 44 } 45 } 46 47 48 allTests.addTest 49 (((Recovery2PCTest) 50 (TestSuite.createTest(Recovery2PCTest.class, 51 "testXARecoverAPI"))). 52 init(0, 0, 0)); 53 allTests.addTest 54 (((Recovery2PCTest) 55 (TestSuite.createTest(Recovery2PCTest.class, 56 "testXARecoverAPI"))). 57 init(1, 0, 0)); 58 allTests.addTest 59 (((Recovery2PCTest) 60 (TestSuite.createTest(Recovery2PCTest.class, 61 "testXARecoverArgCheck"))). 62 init(0, 0, 0)); 63 return allTests; 64 } 65 66 public Recovery2PCTest() { 67 super(true); 68 } 69 70 private Recovery2PCTest init(int explicitTxn, 71 int commit, 72 int recover) { 73 this.explicitTxn = (explicitTxn == 0); 74 this.commit = (commit == 0); 75 this.recover = (recover == 0); 76 return this; 77 } 78 79 private String opName() { 80 StringBuffer sb = new StringBuffer (); 81 82 if (explicitTxn) { 83 sb.append("Exp"); 84 } else { 85 sb.append("Imp"); 86 } 87 88 sb.append("/"); 89 90 if (commit) { 91 sb.append("C"); 92 } else { 93 sb.append("A"); 94 } 95 96 sb.append("/"); 97 98 if (recover) { 99 sb.append("Rec"); 100 } else { 101 sb.append("No Rec"); 102 } 103 104 return sb.toString(); 105 } 106 107 public void tearDown() 108 throws IOException , DatabaseException { 109 110 111 setName(getName() + ": " + opName()); 112 super.tearDown(); 113 } 114 115 public void testBasic() 116 throws Throwable { 117 118 createXAEnvAndDbs(1 << 20, false, NUM_DBS); 119 XAEnvironment xaEnv = (XAEnvironment) env; 120 int numRecs = NUM_RECS * 3; 121 122 try { 123 124 Hashtable expectedData = new Hashtable (); 125 126 127 XidImpl xid = new XidImpl(1, "TwoPCTest1".getBytes(), null); 128 Transaction txn = null; 129 if (explicitTxn) { 130 txn = env.beginTransaction(null, null); 131 xaEnv.setXATransaction(xid, txn); 132 } else { 133 xaEnv.start(xid, 0); 134 } 135 insertData(txn, 0, numRecs - 1, expectedData, 1, commit, NUM_DBS); 136 if (!explicitTxn) { 137 xaEnv.end(xid, 0); 138 } 139 140 xaEnv.prepare(xid); 141 142 if (recover) { 143 closeEnv(); 144 xaRecoverOnly(NUM_DBS); 145 xaEnv = (XAEnvironment) env; 146 } 147 148 if (commit) { 149 xaEnv.commit(xid, false); 150 } else { 151 xaEnv.rollback(xid); 152 } 153 154 if (recover) { 155 verifyData(expectedData, commit, NUM_DBS); 156 forceCloseEnvOnly(); 157 } else { 158 closeEnv(); 159 } 160 xaRecoverAndVerify(expectedData, NUM_DBS); 161 } catch (Throwable t) { 162 163 t.printStackTrace(); 164 throw t; 165 } 166 } 167 168 public void testXARecoverAPI() 169 throws Throwable { 170 171 createXAEnvAndDbs(1 << 20, false, NUM_DBS << 1); 172 final XAEnvironment xaEnv = (XAEnvironment) env; 173 final int numRecs = NUM_RECS * 3; 174 175 try { 176 177 final Hashtable expectedData1 = new Hashtable (); 178 final Hashtable expectedData2 = new Hashtable (); 179 180 181 final Transaction txn1 = 182 (explicitTxn ? 183 env.beginTransaction(null, null) : 184 null); 185 final Transaction txn2 = 186 (explicitTxn ? 187 env.beginTransaction(null, null) : 188 null); 189 final XidImpl xid1 = new XidImpl(1, "TwoPCTest1".getBytes(), null); 190 final XidImpl xid2 = new XidImpl(1, "TwoPCTest2".getBytes(), null); 191 192 Thread thread1 = new Thread () { 193 public void run() { 194 try { 195 if (explicitTxn) { 196 xaEnv.setXATransaction(xid1, txn1); 197 } else { 198 xaEnv.start(xid1, 0); 199 } 200 Thread.yield(); 201 insertData(txn1, 0, numRecs - 1, expectedData1, 1, 202 true, 0, NUM_DBS); 203 Thread.yield(); 204 if (!explicitTxn) { 205 xaEnv.end(xid1, 0); 206 } 207 Thread.yield(); 208 } catch (Exception E) { 209 fail("unexpected: " + E); 210 } 211 } 212 }; 213 214 Thread thread2 = new Thread () { 215 public void run() { 216 try { 217 if (explicitTxn) { 218 xaEnv.setXATransaction(xid2, txn2); 219 } else { 220 xaEnv.start(xid2, 0); 221 } 222 Thread.yield(); 223 insertData(txn2, numRecs, numRecs << 1, 224 expectedData2, 1, false, NUM_DBS, 225 NUM_DBS << 1); 226 Thread.yield(); 227 if (!explicitTxn) { 228 xaEnv.end(xid2, 0); 229 } 230 Thread.yield(); 231 } catch (Exception E) { 232 fail("unexpected: " + E); 233 } 234 } 235 }; 236 237 thread1.start(); 238 thread2.start(); 239 thread1.join(); 240 thread2.join(); 241 242 xaEnv.prepare(xid1); 243 try { 244 xaEnv.prepare(xid1); 245 fail("should have thrown XID has already been registered"); 246 } catch (XAException XAE) { 247 } 249 xaEnv.prepare(xid2); 250 251 XAEnvironment xaEnv2 = xaEnv; 252 Xid [] unfinishedXAXids = xaEnv2.recover(0); 253 assertTrue(unfinishedXAXids.length == 2); 254 boolean sawXid1 = false; 255 boolean sawXid2 = false; 256 for (int i = 0; i < 2; i++) { 257 if (unfinishedXAXids[i].equals(xid1)) { 258 if (sawXid1) { 259 fail("saw Xid1 twice"); 260 } 261 sawXid1 = true; 262 } 263 if (unfinishedXAXids[i].equals(xid2)) { 264 if (sawXid2) { 265 fail("saw Xid2 twice"); 266 } 267 sawXid2 = true; 268 } 269 } 270 assertTrue(sawXid1 && sawXid2); 271 272 closeEnv(); 273 xaEnv2 = (XAEnvironment) env; 274 xaRecoverOnly(NUM_DBS); 275 xaEnv2 = (XAEnvironment) env; 276 277 unfinishedXAXids = xaEnv2.recover(0); 278 assertTrue(unfinishedXAXids.length == 2); 279 sawXid1 = false; 280 sawXid2 = false; 281 for (int i = 0; i < 2; i++) { 282 if (unfinishedXAXids[i].equals(xid1)) { 283 if (sawXid1) { 284 fail("saw Xid1 twice"); 285 } 286 sawXid1 = true; 287 } 288 if (unfinishedXAXids[i].equals(xid2)) { 289 if (sawXid2) { 290 fail("saw Xid2 twice"); 291 } 292 sawXid2 = true; 293 } 294 } 295 assertTrue(sawXid1 && sawXid2); 296 297 xaEnv2 = (XAEnvironment) env; 298 xaEnv2.getXATransaction(xid1); 299 xaEnv2.getXATransaction(xid2); 300 xaEnv2.commit(xid1, false); 301 xaEnv2.rollback(xid2); 302 verifyData(expectedData1, false, 0, NUM_DBS); 303 verifyData(expectedData2, false, NUM_DBS, NUM_DBS << 1); 304 forceCloseEnvOnly(); 305 xaRecoverOnly(NUM_DBS); 306 verifyData(expectedData1, false, 0, NUM_DBS); 307 verifyData(expectedData2, false, NUM_DBS, NUM_DBS << 1); 308 } catch (Throwable t) { 309 310 t.printStackTrace(); 311 throw t; 312 } 313 } 314 315 public void testXARecoverArgCheck() 316 throws Throwable { 317 318 createXAEnvAndDbs(1 << 20, false, NUM_DBS); 319 XAEnvironment xaEnv = (XAEnvironment) env; 320 321 try { 322 XidImpl xid = new XidImpl(1, "TwoPCTest1".getBytes(), null); 323 324 325 try { 326 xaEnv.start(xid, XAResource.TMJOIN | XAResource.TMRESUME); 327 fail("Expected XAException(XAException.XAER_INVAL)"); 328 } catch (XAException XAE) { 329 330 assertTrue(XAE.errorCode == XAException.XAER_INVAL); 331 } 332 333 337 try { 338 xaEnv.start(xid, XAResource.TMSUSPEND); 339 fail("Expected XAException(XAException.XAER_INVAL)"); 340 } catch (XAException XAE) { 341 342 assertTrue(XAE.errorCode == XAException.XAER_INVAL); 343 } 344 345 xaEnv.start(xid, XAResource.TMNOFLAGS); 346 try { 347 xaEnv.start(xid, XAResource.TMNOFLAGS); 348 fail("Expected XAER_DUPID"); 349 } catch (XAException XAE) { 350 351 assertTrue(XAE.errorCode == XAException.XAER_DUPID); 352 } 353 xaEnv.end(xid, XAResource.TMNOFLAGS); 354 355 358 try { 359 xid = new XidImpl(1, "TwoPCTest2".getBytes(), null); 360 xaEnv.start(xid, XAResource.TMJOIN); 361 fail("Expected XAER_NOTA"); 362 } catch (XAException XAE) { 363 364 assertTrue(XAE.errorCode == XAException.XAER_NOTA); 365 } 366 367 370 try { 371 xaEnv.start(xid, XAResource.TMRESUME); 372 fail("Expected XAER_NOTA"); 373 } catch (XAException XAE) { 374 375 assertTrue(XAE.errorCode == XAException.XAER_NOTA); 376 } 377 378 382 Xid xid2 = new XidImpl(1, "TwoPCTest3".getBytes(), null); 383 xaEnv.start(xid2, XAResource.TMNOFLAGS); 384 xaEnv.end(xid2, XAResource.TMNOFLAGS); 385 xid = new XidImpl(1, "TwoPCTest2".getBytes(), null); 386 xaEnv.start(xid, XAResource.TMNOFLAGS); 387 try { 388 xaEnv.start(xid2, XAResource.TMJOIN); 389 fail("Expected XAER_PROTO"); 390 } catch (XAException XAE) { 391 392 assertTrue(XAE.errorCode == XAException.XAER_PROTO); 393 } 394 395 399 try { 400 xid = new XidImpl(1, "TwoPCTest2".getBytes(), null); 401 xaEnv.start(xid, XAResource.TMRESUME); 402 fail("Expected XAER_PROTO"); 403 } catch (XAException XAE) { 404 405 assertTrue(XAE.errorCode == XAException.XAER_PROTO); 406 } 407 408 411 try { 412 xid = new XidImpl(1, "TwoPCTest2".getBytes(), null); 413 xaEnv.end(xid, XAResource.TMFAIL | XAResource.TMSUCCESS); 414 fail("Expected XAER_INVAL"); 415 } catch (XAException XAE) { 416 417 assertTrue(XAE.errorCode == XAException.XAER_INVAL); 418 } 419 420 423 try { 424 xid = new XidImpl(1, "TwoPCTest2".getBytes(), null); 425 xaEnv.end(xid, XAResource.TMFAIL | XAResource.TMSUSPEND); 426 fail("Expected XAER_INVAL"); 427 } catch (XAException XAE) { 428 429 assertTrue(XAE.errorCode == XAException.XAER_INVAL); 430 } 431 432 435 try { 436 xid = new XidImpl(1, "TwoPCTest2".getBytes(), null); 437 xaEnv.end(xid, XAResource.TMSUCCESS | XAResource.TMSUSPEND); 438 fail("Expected XAER_INVAL"); 439 } catch (XAException XAE) { 440 441 assertTrue(XAE.errorCode == XAException.XAER_INVAL); 442 } 443 444 447 Xid xid4 = new XidImpl(1, "TwoPCTest4".getBytes(), null); 448 xaEnv.start(xid4, XAResource.TMNOFLAGS); 449 Transaction txn4 = xaEnv.getThreadTransaction(); 450 assertTrue(txn4 != null); 451 xaEnv.end(xid4, XAResource.TMSUSPEND); 452 assertTrue(xaEnv.getThreadTransaction() == null); 453 Xid xid5 = new XidImpl(1, "TwoPCTest5".getBytes(), null); 454 xaEnv.start(xid5, XAResource.TMNOFLAGS); 455 Transaction txn5 = xaEnv.getThreadTransaction(); 456 xaEnv.end(xid5, XAResource.TMSUSPEND); 457 assertTrue(xaEnv.getThreadTransaction() == null); 458 xaEnv.start(xid4, XAResource.TMRESUME); 459 assertTrue(xaEnv.getThreadTransaction().equals(txn4)); 460 xaEnv.end(xid4, XAResource.TMNOFLAGS); 461 xaEnv.start(xid5, XAResource.TMRESUME); 462 assertTrue(xaEnv.getThreadTransaction().equals(txn5)); 463 xaEnv.end(xid5, XAResource.TMNOFLAGS); 464 465 468 try { 469 xid = new XidImpl(1, "TwoPCTest6".getBytes(), null); 470 xaEnv.start(xid, XAResource.TMNOFLAGS); 471 xaEnv.end(xid, XAResource.TMFAIL); 472 xaEnv.commit(xid, false); 473 } catch (XAException XAE) { 474 475 assertTrue(XAE.errorCode == XAException.XA_RBROLLBACK); 476 } 477 xaEnv.rollback(xid); 478 479 482 xid = new XidImpl(1, "TwoPCTest6".getBytes(), null); 483 xaEnv.start(xid, XAResource.TMNOFLAGS); 484 xaEnv.end(xid, XAResource.TMSUCCESS); 485 xaEnv.commit(xid, false); 486 487 491 xid = new XidImpl(1, "TwoPCTest7".getBytes(), null); 492 xaEnv.start(xid, XAResource.TMNOFLAGS); 493 xaEnv.end(xid, XAResource.TMSUSPEND); 494 xaEnv.end(xid, XAResource.TMSUCCESS); 495 xaEnv.commit(xid, false); 496 497 501 try { 502 xid = new XidImpl(1, "TwoPCTest8".getBytes(), null); 503 xaEnv.end(xid, XAResource.TMFAIL); 504 xaEnv.commit(xid, false); 505 } catch (XAException XAE) { 506 507 assertTrue(XAE.errorCode == XAException.XAER_NOTA); 508 } 509 } catch (Throwable t) { 510 t.printStackTrace(); 511 throw t; 512 } 513 } 514 } 515 | Popular Tags |