1 8 9 package com.sleepycat.je.txn; 10 11 import java.util.HashMap ; 12 import java.util.HashSet ; 13 import java.util.Hashtable ; 14 import java.util.Iterator ; 15 import java.util.Map ; 16 import java.util.Set ; 17 18 import com.sleepycat.je.Database; 19 import com.sleepycat.je.DatabaseException; 20 import com.sleepycat.je.DeadlockException; 21 import com.sleepycat.je.DbInternal; 22 import com.sleepycat.je.LockNotGrantedException; 23 import com.sleepycat.je.LockStats; 24 import com.sleepycat.je.OperationStatus; 25 import com.sleepycat.je.dbi.CursorImpl; 26 import com.sleepycat.je.dbi.DatabaseImpl; 27 import com.sleepycat.je.dbi.EnvironmentImpl; 28 import com.sleepycat.je.tree.BIN; 29 import com.sleepycat.je.tree.BINReference; 30 import com.sleepycat.je.tree.Key; 31 32 40 public abstract class Locker { 41 private static final String DEBUG_NAME = Locker.class.getName(); 42 protected EnvironmentImpl envImpl; 43 protected LockManager lockManager; 44 45 protected long id; protected boolean readUncommittedDefault; 48 49 protected boolean defaultNoWait; protected long lockTimeOutMillis; private long txnTimeOutMillis; private long txnStartMillis; 54 private Lock waitingFor; 57 61 protected Map deleteInfo; 62 63 71 protected Map handleLockToHandleMap; protected Map handleToHandleLockMap; 74 79 protected Thread thread; 80 81 90 public Locker(EnvironmentImpl envImpl, 91 boolean readUncommittedDefault, 92 boolean noWait) 93 throws DatabaseException { 94 95 TxnManager txnManager = envImpl.getTxnManager(); 96 this.id = generateId(txnManager); 97 this.envImpl = envImpl; 98 lockManager = txnManager.getLockManager(); 99 this.readUncommittedDefault = readUncommittedDefault; 100 this.waitingFor = null; 101 102 103 defaultNoWait = noWait; 104 lockTimeOutMillis = envImpl.getLockTimeout(); 105 106 110 txnTimeOutMillis = envImpl.getTxnTimeout(); 111 112 if (txnTimeOutMillis != 0) { 113 txnStartMillis = System.currentTimeMillis(); 114 } else { 115 txnStartMillis = 0; 116 } 117 118 119 thread = Thread.currentThread(); 120 121 125 } 126 127 130 Locker() { 131 } 132 133 138 protected abstract long generateId(TxnManager txnManager); 139 140 143 public long getId() { 144 return id; 145 } 146 147 150 public boolean getDefaultNoWait() { 151 return defaultNoWait; 152 } 153 154 157 public synchronized long getLockTimeout() { 158 return lockTimeOutMillis; 159 } 160 161 165 public synchronized void setLockTimeout(long timeOutMillis) { 166 lockTimeOutMillis = timeOutMillis; 167 } 168 169 172 public synchronized void setTxnTimeout(long timeOutMillis) { 173 txnTimeOutMillis = timeOutMillis; 174 txnStartMillis = System.currentTimeMillis(); 175 } 176 177 181 public boolean isReadUncommittedDefault() { 182 return readUncommittedDefault; 183 } 184 185 Lock getWaitingFor() { 186 return waitingFor; 187 } 188 189 void setWaitingFor(Lock lock) { 190 waitingFor = lock; 191 } 192 193 196 void setOnlyAbortable() { 197 198 } 199 200 protected abstract void checkState(boolean ignoreCalledByAbort) 201 throws DatabaseException; 202 203 206 207 226 abstract LockResult lockInternal(long nodeId, 227 LockType lockType, 228 boolean noWait, 229 DatabaseImpl database) 230 throws DeadlockException, DatabaseException; 231 232 251 public LockResult lock(long nodeId, 252 LockType lockType, 253 boolean noWait, 254 DatabaseImpl database) 255 throws LockNotGrantedException, DeadlockException, DatabaseException { 256 257 LockResult result = lockInternal(nodeId, lockType, noWait, database); 258 259 if (result.getLockGrant() == LockGrantType.DENIED) { 260 261 throw new LockNotGrantedException("Non-blocking lock was denied."); 262 } else { 263 return result; 264 } 265 } 266 267 283 public LockResult nonBlockingLock(long nodeId, 284 LockType lockType, 285 DatabaseImpl database) 286 throws DatabaseException { 287 288 return lockInternal(nodeId, lockType, true, database); 289 } 290 291 295 public void releaseLock(long nodeId) 296 throws DatabaseException { 297 298 304 lockManager.release(nodeId, this); 305 } 306 307 310 public void demoteLock(long nodeId) 311 throws DatabaseException { 312 313 317 lockManager.demote(nodeId, this); 318 } 319 320 323 public abstract boolean isTransactional(); 324 325 328 public abstract boolean isSerializableIsolation(); 329 330 333 public abstract boolean isReadCommittedIsolation(); 334 335 340 public abstract Txn getTxnLocker(); 341 342 350 public abstract Locker newNonTxnLocker() 351 throws DatabaseException; 352 353 361 public abstract void releaseNonTxnLocks() 362 throws DatabaseException; 363 364 372 public boolean sharesLocksWith(Locker other) { 373 if (other instanceof BuddyLocker) { 374 BuddyLocker buddy = (BuddyLocker) other; 375 return buddy.getBuddy() == this; 376 } else { 377 return false; 378 } 379 } 380 381 384 public abstract void operationEnd() 385 throws DatabaseException; 386 387 395 public abstract void operationEnd(boolean operationOK) 396 throws DatabaseException; 397 398 402 public abstract void setHandleLockOwner(boolean operationOK, 403 Database dbHandle, 404 boolean dbIsClosing) 405 throws DatabaseException; 406 407 410 public void operationEnd(OperationStatus status) 411 throws DatabaseException { 412 413 operationEnd(status == OperationStatus.SUCCESS); 414 } 415 416 419 public abstract void registerCursor(CursorImpl cursor) 420 throws DatabaseException; 421 422 425 public abstract void unRegisterCursor(CursorImpl cursor) 426 throws DatabaseException; 427 428 431 432 435 public abstract long getAbortLsn(long nodeId) 436 throws DatabaseException; 437 438 441 public abstract WriteLockInfo getWriteLockInfo(long nodeId) 442 throws DatabaseException; 443 444 449 public abstract void markDeleteAtTxnEnd(DatabaseImpl db, 450 boolean deleteAtCommit) 451 throws DatabaseException; 452 453 457 public void addDeleteInfo(BIN bin, Key deletedKey) 458 throws DatabaseException { 459 460 synchronized (this) { 461 462 if (deleteInfo == null) { 463 deleteInfo = new HashMap (); 464 } 465 Long nodeId = new Long (bin.getNodeId()); 466 BINReference binRef = (BINReference) deleteInfo.get(nodeId); 467 if (binRef == null) { 468 binRef = bin.createReference(); 469 deleteInfo.put(nodeId, binRef); 470 } 471 binRef.addDeletedKey(deletedKey); 472 } 473 } 474 475 480 481 484 abstract void addLock(Long nodeId, 485 Lock lock, 486 LockType type, 487 LockGrantType grantStatus) 488 throws DatabaseException; 489 490 494 public abstract boolean createdNode(long nodeId) 495 throws DatabaseException; 496 497 502 abstract void removeLock(long nodeId, Lock lock) 503 throws DatabaseException; 504 505 509 abstract void moveWriteToReadLock(long nodeId, Lock lock); 510 511 514 public abstract LockStats collectStats(LockStats stats) 515 throws DatabaseException; 516 517 521 boolean isTimedOut() 522 throws DatabaseException { 523 524 if (txnStartMillis != 0) { 525 long diff = System.currentTimeMillis() - txnStartMillis; 526 if (diff > txnTimeOutMillis) { 527 return true; 528 } 529 } 530 return false; 531 } 532 533 534 public long getTxnTimeOut() { 535 return txnTimeOutMillis; 536 } 537 538 long getTxnStartMillis() { 539 return txnStartMillis; 540 } 541 542 545 void unregisterHandle(Database dbHandle) { 546 547 553 if (handleToHandleLockMap != null) { 554 handleToHandleLockMap.remove(dbHandle); 555 } 556 } 557 558 561 public void addToHandleMaps(Long handleLockId, 562 Database databaseHandle) { 563 Set dbHandleSet = null; 565 if (handleLockToHandleMap == null) { 566 567 571 handleLockToHandleMap = new Hashtable (); 572 handleToHandleLockMap = new Hashtable (); 573 } else { 574 dbHandleSet = (Set ) handleLockToHandleMap.get(handleLockId); 575 } 576 577 if (dbHandleSet == null) { 578 dbHandleSet = new HashSet (); 579 handleLockToHandleMap.put(handleLockId, dbHandleSet); 580 } 581 582 583 dbHandleSet.add(databaseHandle); 584 585 handleToHandleLockMap.put(databaseHandle, handleLockId); 586 } 587 588 592 public boolean isHandleLockTransferrable() { 593 return true; 594 } 595 596 600 void transferHandleLockToHandle(Database dbHandle) 601 throws DatabaseException { 602 603 607 Locker holderTxn = new BasicLocker(envImpl); 608 transferHandleLock(dbHandle, holderTxn, true ); 609 } 610 611 614 public void transferHandleLock(Database dbHandle, 615 Locker destLocker, 616 boolean demoteToRead) 617 throws DatabaseException { 618 619 624 if (DbInternal.dbGetDatabaseImpl(dbHandle) != null) { 625 Long handleLockId = (Long ) handleToHandleLockMap.get(dbHandle); 626 if (handleLockId != null) { 627 628 long nodeId = handleLockId.longValue(); 629 630 631 lockManager.transfer(nodeId, this, destLocker, demoteToRead); 632 633 637 destLocker.addToHandleMaps(handleLockId, dbHandle); 638 639 640 Set dbHandleSet = (Set ) 641 handleLockToHandleMap.get(handleLockId); 642 Iterator iter = dbHandleSet.iterator(); 643 while (iter.hasNext()) { 644 if (((Database) iter.next()) == dbHandle) { 645 iter.remove(); 646 break; 647 } 648 } 649 if (dbHandleSet.size() == 0) { 650 handleLockToHandleMap.remove(handleLockId); 651 } 652 653 656 DbInternal.dbSetHandleLocker(dbHandle, destLocker); 657 } 658 } 659 } 660 661 664 public String toString() { 665 String className = getClass().getName(); 666 className = className.substring(className.lastIndexOf('.') + 1); 667 668 return Long.toString(id) + "_" + 669 ((thread == null) ? "" : thread.getName()) + "_" + 670 className; 671 } 672 673 676 public void dumpLockTable() 677 throws DatabaseException { 678 679 lockManager.dump(); 680 } 681 } 682 | Popular Tags |