1 package org.apache.ojb.odmg; 2 3 4 import java.io.Serializable ; 5 import java.util.Collection ; 6 import java.util.List ; 7 8 import org.apache.ojb.broker.PersistenceBroker; 9 import org.apache.ojb.broker.PersistenceBrokerFactory; 10 import org.apache.ojb.broker.TestHelper; 11 import org.apache.ojb.broker.query.Criteria; 12 import org.apache.ojb.broker.query.QueryFactory; 13 import org.apache.ojb.junit.OJBTestCase; 14 import org.apache.ojb.odmg.locking.LockManager; 15 import org.apache.ojb.odmg.locking.LockManagerFactory; 16 import org.apache.ojb.odmg.shared.Article; 17 import org.apache.commons.beanutils.PropertyUtils; 18 import org.apache.commons.lang.builder.ToStringBuilder; 19 import org.apache.commons.lang.builder.EqualsBuilder; 20 import org.odmg.Database; 21 import org.odmg.Implementation; 22 import org.odmg.LockNotGrantedException; 23 import org.odmg.OQLQuery; 24 import org.odmg.Transaction; 25 26 29 public class LockingTest extends OJBTestCase 30 { 31 public static void main(String [] args) 32 { 33 String [] arr = {LockingTest.class.getName()}; 34 junit.textui.TestRunner.main(arr); 35 } 36 37 private static String PRE = "LockingTest_" + System.currentTimeMillis() + "_"; 38 39 private Implementation odmg1; 40 private Database db1; 41 42 private Implementation odmg2; 43 private Database db2; 44 45 public LockingTest(String name) 46 { 47 super(name); 48 } 49 50 public void setUp() throws Exception 51 { 52 super.setUp(); 53 String databaseName = TestHelper.DEF_DATABASE_NAME; 54 55 odmg1 = OJB.getInstance(); 56 db1 = odmg1.newDatabase(); 57 db1.open(databaseName, Database.OPEN_READ_WRITE); 58 59 odmg2 = OJB.getInstance(); 60 db2 = odmg2.newDatabase(); 61 db2.open(databaseName, Database.OPEN_READ_WRITE); 62 63 } 64 65 public void tearDown() throws Exception 66 { 67 if(odmg1.currentTransaction() != null) odmg1.currentTransaction().abort(); 68 db1.close(); 69 70 if(odmg2.currentTransaction() != null) odmg2.currentTransaction().abort(); 71 db2.close(); 72 super.tearDown(); 73 } 74 75 public void testWrite_1() throws Exception 76 { 77 String name = "testWrite_1_" + System.currentTimeMillis(); 78 LockObject bean = new LockObject(name + "_bean_dummy"); 79 80 performSaveMethod(bean.getId(), bean); 81 82 Transaction tx = odmg1.newTransaction(); 83 tx.begin(); 84 OQLQuery query = odmg1.newOQLQuery(); 85 query.create("select objs from " + LockObject.class.getName() + " where value = $1"); 86 query.bind(name + "_bean_dummy"); 87 List result = (List ) query.execute(); 88 tx.commit(); 89 assertEquals(1, result.size()); 90 LockObject tmp = (LockObject) result.get(0); 91 assertEquals(bean, tmp); 92 } 93 94 public void testWrite_2() throws Exception 95 { 96 String name = "testWrite_2_" + System.currentTimeMillis(); 97 98 Transaction tx = odmg1.newTransaction(); 99 tx.begin(); 100 LockObject tmp = new LockObject(name + "_temp"); 101 db1.makePersistent(tmp); 102 tx.commit(); 103 104 LockObject bean = new LockObject(name + "_bean_dummy"); 105 bean.setId(tmp.getId()); 106 107 performSaveMethod(tmp.getId(), bean); 108 109 tx = odmg1.newTransaction(); 110 tx.begin(); 111 OQLQuery query = odmg1.newOQLQuery(); 112 query.create("select objs from " + LockObject.class.getName() + " where value = $1"); 113 query.bind(name + "_bean_dummy"); 114 List result = (List ) query.execute(); 115 tx.commit(); 116 assertEquals(1, result.size()); 117 tmp = (LockObject) result.get(0); 118 assertEquals(bean, tmp); 119 } 120 121 124 private LockObject performSaveMethod(Integer testId, LockObject bean) throws Exception 125 { 126 LockObject toBeEdited = null; 127 Transaction tx = odmg1.newTransaction(); 128 tx.begin(); 129 OQLQuery query = odmg1.newOQLQuery(); 130 query.create("select objs from " + LockObject.class.getName() + " where id = $1"); 131 query.bind(testId); 132 List result = (List ) query.execute(); 133 if(result.size() != 0) 134 { 135 toBeEdited = (LockObject) result.get(0); 136 if(toBeEdited != null) 137 { 138 try 139 { 140 PropertyUtils.copyProperties(toBeEdited, bean); 141 tx.commit(); 142 } 143 catch(Exception e) 144 { 145 e.printStackTrace(); 146 fail("Unexpected exception: " + e.getMessage()); 147 } 148 tx = odmg1.newTransaction(); 150 tx.begin(); 151 tx.lock(toBeEdited, Transaction.UPGRADE); 152 tx.commit(); 153 } 154 else 155 { 156 tx.abort(); 157 } 158 } 159 else 160 { 161 try 162 { 163 tx.lock(bean, Transaction.WRITE); 164 tx.commit(); 165 } 166 catch(Exception e) 167 { 168 e.printStackTrace(); 169 fail("Unexpected exception: " + e.getMessage()); 170 } 171 } 172 return toBeEdited; 173 } 174 175 178 public void testMultipleLocks() throws Exception 179 { 180 long timestamp = System.currentTimeMillis(); 181 String name = "testMultipleLocks_" + timestamp; 182 String nameUpdated = "testMultipleLocks_Updated_" + timestamp; 183 TransactionExt tx = (TransactionExt) odmg1.newTransaction(); 184 LockObjectOpt obj = new LockObjectOpt(); 185 tx.begin(); 186 tx.lock(obj, Transaction.WRITE); 187 obj.setValue(name); 188 tx.lock(obj, Transaction.WRITE); 189 tx.lock(obj, Transaction.UPGRADE); 190 tx.commit(); 191 192 OQLQuery query = odmg1.newOQLQuery(); 193 query.create("select all from " + LockObjectOpt.class.getName() + " where value like $1"); 194 query.bind(name); 195 Collection result = (Collection ) query.execute(); 196 assertNotNull(result); 197 assertEquals(1, result.size()); 198 199 tx.begin(); 200 tx.lock(obj, Transaction.WRITE); 201 tx.lock(obj, Transaction.WRITE); 202 obj.setValue(nameUpdated); 203 tx.lock(obj, Transaction.WRITE); 204 tx.lock(obj, Transaction.UPGRADE); 205 tx.commit(); 206 207 query = odmg1.newOQLQuery(); 208 query.create("select all from " + LockObjectOpt.class.getName() + " where value like $1"); 209 query.bind(nameUpdated); 210 result = (Collection ) query.execute(); 211 assertNotNull(result); 212 assertEquals(1, result.size()); 213 } 214 215 public void testLockBasics() throws Exception 216 { 217 TransactionImpl tx1 = (TransactionImpl) odmg1.newTransaction(); 218 TransactionImpl tx2 = (TransactionImpl) odmg2.newTransaction(); 219 220 Article a = new Article(); 221 a.setArticleId(333); 222 223 tx1.begin(); 224 tx2.begin(); 225 LockManager lm = LockManagerFactory.getLockManager(); 226 boolean success1 = lm.writeLock(tx1, a); 227 boolean success2 = lm.writeLock(tx2, a); 228 229 boolean success3 = lm.releaseLock(tx1, a); 230 231 assertTrue("1st lock should succeed", success1); 232 assertTrue("2nd lock should not succeed", !success2); 233 assertTrue("release should succeed", success3); 234 235 try 236 { 237 tx1.abort(); 238 tx2.abort(); 239 } 240 catch(Exception e) 241 { 242 } 243 } 244 245 public void testLockBasics2() throws Exception 246 { 247 TransactionImpl tx1 = (TransactionImpl) odmg1.newTransaction(); 248 TransactionImpl tx2 = (TransactionImpl) odmg2.newTransaction(); 249 250 Article a1 = new Article(); 251 a1.setArticleId(333); 252 253 Article a2 = new Article(); 254 a2.setArticleId(333); 255 256 tx1.begin(); 257 tx2.begin(); 258 LockManager lm = LockManagerFactory.getLockManager(); 259 260 assertFalse(tx1.getGUID().equals(tx2.getGUID())); 261 262 assertTrue("1st lock should succeed", lm.writeLock(tx1, a1)); 263 assertFalse("2nd lock should not succeed", lm.writeLock(tx2, a2)); 264 lm.releaseLock(tx2, a2); 265 lm.releaseLock(tx2, a1); 266 assertFalse(lm.checkWrite(tx2, a1)); 267 assertFalse(lm.checkWrite(tx2, a2)); 268 assertTrue(lm.checkWrite(tx1, a1)); 269 assertTrue(lm.checkWrite(tx1, a2)); 270 assertTrue("release should succeed", lm.releaseLock(tx1, a2)); 273 assertTrue("2nd object lock should succeed", lm.writeLock(tx2, a2)); 274 assertTrue("release 2nd object lock should succeed", lm.releaseLock(tx2, a2)); 275 276 try 277 { 278 tx1.abort(); 279 tx2.abort(); 280 } 281 catch(Exception e) 282 { 283 } 284 } 285 286 290 public void testOptimisticLockBasics() throws Exception 291 { 292 TransactionImpl tx1 = (TransactionImpl) odmg1.newTransaction(); 293 TransactionImpl tx2 = (TransactionImpl) odmg2.newTransaction(); 294 295 LockObjectOpt obj = new LockObjectOpt(); 296 297 298 tx1.begin(); 299 300 tx1.lock(obj, Transaction.WRITE); 301 obj.setValue("tx1"); 302 tx1.commit(); 303 304 obj.setVersion(obj.getVersion() - 1); 305 tx2.begin(); 306 tx2.lock(obj, Transaction.WRITE); 307 308 obj.setValue("tx2"); 309 try 310 { 311 tx2.commit(); 312 fail("Optimistic locking exception expected"); 315 } 316 catch(LockNotGrantedException ex) 317 { 318 assertTrue("expected that a OL exception is caught", true); 319 } 320 catch(Exception e) 321 { 322 e.printStackTrace(); 323 fail("Wrong kind of exception thrown, expected 'LockNotGrantedException', but was " + e.getMessage()); 324 } 325 } 326 327 328 333 private Article createArticle(String name) 334 { 335 Article a = new Article(); 336 337 a.setArticleName(PRE + name); 338 a.setMinimumStock(100); 339 a.setOrderedUnits(17); 340 a.setPrice(0.45); 341 a.setProductGroupId(1); 342 a.setStock(234); 343 a.setSupplierId(4); 344 a.setUnit("bottle"); 345 return a; 346 } 347 348 public void testLockLoop() throws Exception 349 { 350 int loops = 10; 351 Article[] arr = new Article[loops]; 352 for(int i = 0; i < loops; i++) 353 { 354 Article a = createArticle("testLockLoop"); 355 arr[i] = a; 356 } 357 358 TransactionImpl tx = (TransactionImpl) odmg1.newTransaction(); 359 tx.begin(); 360 for(int i = 0; i < arr.length; i++) 361 { 362 tx.lock(arr[i], Transaction.WRITE); 363 } 364 LockManager lm = LockManagerFactory.getLockManager(); 365 boolean success = lm.writeLock(tx, arr[(loops - 2)]); 366 assertTrue("lock should succeed", success); 367 tx.commit(); 368 369 TransactionImpl tx2 = (TransactionImpl) odmg2.newTransaction(); 370 tx2.begin(); 371 success = lm.writeLock(tx2, arr[(loops - 2)]); 372 assertTrue("lock should succeed", success); 373 374 OQLQuery query = odmg2.newOQLQuery(); 375 String sql = "select allArticles from " + Article.class.getName() + 376 " where articleName = \"" + PRE + "testLockLoop" + "\""; 377 query.create(sql); 378 int result = ((List ) query.execute()).size(); 379 tx2.commit(); 380 assertEquals("Wrong number of objects wrote to DB", loops, result); 381 382 PersistenceBroker broker = PersistenceBrokerFactory.defaultPersistenceBroker(); 383 broker.clearCache(); 384 Criteria crit = new Criteria(); 385 crit.addLike("articleName", PRE + "testLockLoop"); 386 result = broker.getCount(QueryFactory.newQuery(Article.class, crit)); 387 broker.close(); 388 assertEquals("Wrong number of objects wrote to DB", loops, result); 389 } 390 391 392 395 public static class LockObject implements Serializable 396 { 397 private Integer id; 398 private String value; 399 400 public LockObject() 401 { 402 } 403 404 public LockObject(String value) 405 { 406 this.value = value; 407 } 408 409 public boolean equals(Object obj) 410 { 411 if(obj == null || !(obj instanceof LockObject)) 412 { 413 return false; 414 } 415 else 416 { 417 LockObject tmp = (LockObject) obj; 418 return new EqualsBuilder() 419 .append(id, tmp.id) 420 .append(value, tmp.value) 421 .isEquals(); 422 } 423 } 424 425 public String toString() 426 { 427 return new ToStringBuilder(this) 428 .append("id", id) 429 .append("value", value) 430 .toString(); 431 } 432 433 public Integer getId() 434 { 435 return id; 436 } 437 public void setId(Integer id) 438 { 439 this.id = id; 440 } 441 public String getValue() 442 { 443 return value; 444 } 445 public void setValue(String value) 446 { 447 this.value = value; 448 } 449 } 450 451 454 public static class LockObjectOpt extends LockObject 455 { 456 private int version; 457 458 public LockObjectOpt() 459 { 460 } 461 462 public LockObjectOpt(String value) 463 { 464 super(value); 465 } 466 467 public boolean equals(Object obj) 468 { 469 if(obj == null || !(obj instanceof LockObjectOpt)) 470 { 471 return false; 472 } 473 else 474 { 475 LockObjectOpt tmp = (LockObjectOpt) obj; 476 return new EqualsBuilder() 477 .append(version, tmp.version) 478 .isEquals() && super.equals(obj); 479 } 480 } 481 482 public String toString() 483 { 484 return new ToStringBuilder(this) 485 .append("super", super.toString()) 486 .append("version", version) 487 .toString(); 488 } 489 490 public int getVersion() 491 { 492 return version; 493 } 494 public void setVersion(int version) 495 { 496 this.version = version; 497 } 498 } 499 } 500 | Popular Tags |