Source Code Cross Referenced for Locker.java in  » JMX » je » com » sleepycat » je » txn » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » JMX » je » com.sleepycat.je.txn 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*-
002:         * See the file LICENSE for redistribution information.
003:         *
004:         * Copyright (c) 2002,2008 Oracle.  All rights reserved.
005:         *
006:         * $Id: Locker.java,v 1.101.2.6 2008/02/21 08:09:03 chao Exp $
007:         */
008:
009:        package com.sleepycat.je.txn;
010:
011:        import java.util.HashMap;
012:        import java.util.HashSet;
013:        import java.util.Hashtable;
014:        import java.util.Iterator;
015:        import java.util.Map;
016:        import java.util.Set;
017:
018:        import com.sleepycat.je.Database;
019:        import com.sleepycat.je.DatabaseException;
020:        import com.sleepycat.je.DbInternal;
021:        import com.sleepycat.je.DeadlockException;
022:        import com.sleepycat.je.LockNotGrantedException;
023:        import com.sleepycat.je.LockStats;
024:        import com.sleepycat.je.OperationStatus;
025:        import com.sleepycat.je.dbi.CursorImpl;
026:        import com.sleepycat.je.dbi.DatabaseImpl;
027:        import com.sleepycat.je.dbi.EnvironmentImpl;
028:        import com.sleepycat.je.tree.BIN;
029:        import com.sleepycat.je.tree.BINReference;
030:        import com.sleepycat.je.tree.Key;
031:
032:        /**
033:         * Locker instances are JE's route to locking and transactional support.  This
034:         * class is the abstract base class for BasicLocker, ThreadLocker, Txn and
035:         * AutoTxn.  Locker instances are in fact only a transaction shell to get to
036:         * the lock manager, and don't guarantee transactional semantics. Txn and
037:         * AutoTxn instances are both truely transactional, but have different ending
038:         * behaviors.
039:         */
040:        public abstract class Locker {
041:            private static final String DEBUG_NAME = Locker.class.getName();
042:            protected EnvironmentImpl envImpl;
043:            protected LockManager lockManager;
044:
045:            protected long id; // transaction id
046:            protected boolean readUncommittedDefault; // read-uncommitted is default
047:
048:            /* Timeouts */
049:            protected boolean defaultNoWait; // true for non-blocking
050:            protected long lockTimeOutMillis; // timeout period for lock, in ms
051:            private long txnTimeOutMillis; // timeout period for txns, in ms
052:            private long txnStartMillis; // for txn timeout determination
053:
054:            private Lock waitingFor; // The lock that this txn is
055:            // waiting for.
056:
057:            /*
058:             * DeleteInfo refers to BINReferences that should be sent to the
059:             * INCompressor for asynchronous compressing after the transaction ends.
060:             */
061:            protected Map deleteInfo;
062:
063:            /*
064:             * To support handle lock transfers, each txn keeps maps handle locks to
065:             * database handles. This is maintained as a map where the key is the
066:             * handle lock id and the value is a set of database handles that
067:             * correspond to that handle lock. This is a 1 - many relationship because
068:             * a single handle lock can cover multiple database handles opened by the
069:             * same transaction.
070:             */
071:            protected Map handleLockToHandleMap; // 1-many, used for commits
072:            protected Map handleToHandleLockMap; // 1-1, used for aborts
073:
074:            /**
075:             * The thread that created this locker.  Used for debugging, and by the
076:             * ThreadLocker subclass. Note that thread may be null if the Locker is
077:             * instantiated by reading the log.
078:             */
079:            protected Thread thread;
080:
081:            /**
082:             * Create a locker id. This constructor is called very often, so it should
083:             * be as streamlined as possible.
084:             *
085:             * @param lockManager lock manager for this environment
086:             * @param readUncommittedDefault if true, this transaction does
087:             * read-uncommitted by default
088:             * @param noWait if true, non-blocking lock requests are used.
089:             */
090:            public Locker(EnvironmentImpl envImpl,
091:                    boolean readUncommittedDefault, boolean noWait)
092:                    throws DatabaseException {
093:
094:                TxnManager txnManager = envImpl.getTxnManager();
095:                this .id = generateId(txnManager);
096:                this .envImpl = envImpl;
097:                lockManager = txnManager.getLockManager();
098:                this .readUncommittedDefault = readUncommittedDefault;
099:                this .waitingFor = null;
100:
101:                /* get the default lock timeout. */
102:                defaultNoWait = noWait;
103:                lockTimeOutMillis = envImpl.getLockTimeout();
104:
105:                /*
106:                 * Check the default txn timeout. If non-zero, remember the txn start
107:                 * time.
108:                 */
109:                txnTimeOutMillis = envImpl.getTxnTimeout();
110:
111:                if (txnTimeOutMillis != 0) {
112:                    txnStartMillis = System.currentTimeMillis();
113:                } else {
114:                    txnStartMillis = 0;
115:                }
116:
117:                /* Save the thread used to create the locker. */
118:                thread = Thread.currentThread();
119:
120:                /*
121:                 * Do lazy initialization of deleteInfo and handle lock maps, to
122:                 * conserve memory.
123:                 */
124:            }
125:
126:            /**
127:             * For reading from the log.
128:             */
129:            Locker() {
130:            }
131:
132:            /**
133:             * A Locker has to generate its next id. Some subtypes, like BasicLocker,
134:             * have a single id for all instances because they are never used for
135:             * recovery. Other subtypes ask the txn manager for an id.
136:             */
137:            protected abstract long generateId(TxnManager txnManager);
138:
139:            /**
140:             * @return the transaction's id.
141:             */
142:            public long getId() {
143:                return id;
144:            }
145:
146:            /**
147:             * @return the default no-wait (non-blocking) setting.
148:             */
149:            public boolean getDefaultNoWait() {
150:                return defaultNoWait;
151:            }
152:
153:            /**
154:             * Get the lock timeout period for this transaction, in milliseconds
155:             */
156:            public synchronized long getLockTimeout() {
157:                return lockTimeOutMillis;
158:            }
159:
160:            /**
161:             * Set the lock timeout period for any locks in this transaction,
162:             * in milliseconds.
163:             *
164:             * @param timeout The timeout value for the transaction lifetime, in
165:             * milliseconds. A value of 0 disables timeouts for the transaction.
166:             *
167:             * @throws IllegalArgumentException If the value of timeout is negative.
168:             */
169:            public synchronized void setLockTimeout(long timeout) {
170:
171:                if (timeout < 0) {
172:                    throw new IllegalArgumentException(
173:                            "the timeout value cannot be negative");
174:                }
175:
176:                lockTimeOutMillis = timeout;
177:            }
178:
179:            /**
180:             * Set the timeout period for this transaction, in milliseconds.
181:             *
182:             * @param timeout The timeout value for the transaction lifetime, in
183:             * milliseconds. A value of 0 disables timeouts for the transaction.
184:             *
185:             * @throws IllegalArgumentException If the value of timeout is negative.
186:             */
187:            public synchronized void setTxnTimeout(long timeout) {
188:
189:                if (timeout < 0) {
190:                    throw new IllegalArgumentException(
191:                            "the timeout value cannot be negative");
192:                }
193:
194:                txnTimeOutMillis = timeout;
195:                if (txnTimeOutMillis != 0) {
196:                    txnStartMillis = System.currentTimeMillis();
197:                } else {
198:                    txnStartMillis = 0;
199:                }
200:            }
201:
202:            /**
203:             * @return true if transaction was created with read-uncommitted as a
204:             * default.
205:             */
206:            public boolean isReadUncommittedDefault() {
207:                return readUncommittedDefault;
208:            }
209:
210:            Lock getWaitingFor() {
211:                return waitingFor;
212:            }
213:
214:            void setWaitingFor(Lock lock) {
215:                waitingFor = lock;
216:            }
217:
218:            /**
219:             * Set the state of a transaction to ONLY_ABORTABLE.
220:             */
221:            void setOnlyAbortable() {
222:                /* no-op unless Txn. */
223:            }
224:
225:            protected abstract void checkState(boolean ignoreCalledByAbort)
226:                    throws DatabaseException;
227:
228:            /*
229:             * Obtain and release locks.
230:             */
231:
232:            /**
233:             * Abstract method to a blocking or non-blocking lock of the given type on
234:             * the given nodeId.  Unlike the lock() method, this method does not throw
235:             * LockNotGrantedException and can therefore be used by nonBlockingLock to
236:             * probe for a lock without the overhead of an exception stack trace.
237:             *
238:             * @param nodeId is the node to lock.
239:             *
240:             * @param lockType is the type of lock to request.
241:             *
242:             * @param noWait is true to override the defaultNoWait setting.  If true,
243:             * or if defaultNoWait is true, throws LockNotGrantedException if the lock
244:             * cannot be granted without waiting.
245:             *
246:             * @param database is the database containing nodeId.
247:             *
248:             * @throws DeadlockException if acquiring a blocking lock would result in a
249:             * deadlock.
250:             */
251:            abstract LockResult lockInternal(long nodeId, LockType lockType,
252:                    boolean noWait, DatabaseImpl database)
253:                    throws DeadlockException, DatabaseException;
254:
255:            /**
256:             * Request a blocking or non-blocking lock of the given type on the given
257:             * nodeId.
258:             *
259:             * @param nodeId is the node to lock.
260:             *
261:             * @param lockType is the type of lock to request.
262:             *
263:             * @param noWait is true to override the defaultNoWait setting.  If true,
264:             * or if defaultNoWait is true, throws LockNotGrantedException if the lock
265:             * cannot be granted without waiting.
266:             *
267:             * @param database is the database containing nodeId.
268:             *
269:             * @throws LockNotGrantedException if a non-blocking lock was denied.
270:             *
271:             * @throws DeadlockException if acquiring a blocking lock would result in a
272:             * deadlock.
273:             */
274:            public LockResult lock(long nodeId, LockType lockType,
275:                    boolean noWait, DatabaseImpl database)
276:                    throws LockNotGrantedException, DeadlockException,
277:                    DatabaseException {
278:
279:                LockResult result = lockInternal(nodeId, lockType, noWait,
280:                        database);
281:
282:                if (result.getLockGrant() == LockGrantType.DENIED) {
283:                    /* DENIED can only be returned for a non-blocking lock. */
284:                    throw new LockNotGrantedException(
285:                            "Non-blocking lock was denied.");
286:                } else {
287:                    return result;
288:                }
289:            }
290:
291:            /**
292:             * Request a non-blocking lock of the given type on the given nodeId.
293:             *
294:             * <p>Unlike lock(), this method returns LockGrantType.DENIED if the lock
295:             * is denied rather than throwing LockNotGrantedException.  This method
296:             * should therefore not be used as the final lock for a user operation,
297:             * since in that case LockNotGrantedException should be thrown for a denied
298:             * lock.  It is normally used only to probe for a lock, and other recourse
299:             * is taken if the lock is denied.</p>
300:             *
301:             * @param nodeId is the node to lock.
302:             *
303:             * @param lockType is the type of lock to request.
304:             *
305:             * @param database is the database containing nodeId.
306:             */
307:            public LockResult nonBlockingLock(long nodeId, LockType lockType,
308:                    DatabaseImpl database) throws DatabaseException {
309:
310:                return lockInternal(nodeId, lockType, true, database);
311:            }
312:
313:            /**
314:             * Release the lock on this LN and remove from the transaction's owning
315:             * set.
316:             */
317:            public void releaseLock(long nodeId) throws DatabaseException {
318:
319:                lockManager.release(nodeId, this );
320:                removeLock(nodeId);
321:            }
322:
323:            /**
324:             * Revert this lock from a write lock to a read lock.
325:             */
326:            public void demoteLock(long nodeId) throws DatabaseException {
327:
328:                /*
329:                 * If successful, the lock manager will call back to the transaction
330:                 * and adjust the location of the lock in the lock collection.
331:                 */
332:                lockManager.demote(nodeId, this );
333:            }
334:
335:            /**
336:             * Returns whether this locker is transactional.
337:             */
338:            public abstract boolean isTransactional();
339:
340:            /**
341:             * Returns whether the isolation level of this locker is serializable.
342:             */
343:            public abstract boolean isSerializableIsolation();
344:
345:            /**
346:             * Returns whether the isolation level of this locker is read-committed.
347:             */
348:            public abstract boolean isReadCommittedIsolation();
349:
350:            /**
351:             * Returns the underlying Txn if the locker is transactional, or null if
352:             * the locker is non-transactional.  For a Txn-based locker, this method
353:             * returns 'this'.  For a BuddyLocker, this method may returns the buddy.
354:             */
355:            public abstract Txn getTxnLocker();
356:
357:            /**
358:             * Creates a fresh non-transactional locker, while retaining any
359:             * transactional locks held by this locker.  This method is called when the
360:             * cursor for this locker is cloned.
361:             *
362:             * <p>In general, transactional lockers return 'this' when this method is
363:             * called, while non-transactional lockers return a new instance.</p>
364:             */
365:            public abstract Locker newNonTxnLocker() throws DatabaseException;
366:
367:            /**
368:             * Releases any non-transactional locks held by this locker.  This method
369:             * is called when the cursor moves to a new position or is closed.
370:             *
371:             * <p>In general, transactional lockers do nothing when this method is
372:             * called, while non-transactional lockers release all locks as if
373:             * operationEnd were called.</p>
374:             */
375:            public abstract void releaseNonTxnLocks() throws DatabaseException;
376:
377:            /**
378:             * Returns whether this locker can share locks with the given locker.
379:             *
380:             * <p>All lockers share locks with a BuddyLocker whose buddy is this
381:             * locker.  To support BuddyLocker when overriding this method, always
382:             * return true if this implementation (super.sharesLocksWith(...)) returns
383:             * true.</p>
384:             */
385:            public boolean sharesLocksWith(Locker other) {
386:                if (other instanceof  BuddyLocker) {
387:                    BuddyLocker buddy = (BuddyLocker) other;
388:                    return buddy.getBuddy() == this ;
389:                } else {
390:                    return false;
391:                }
392:            }
393:
394:            /**
395:             * The equivalent of calling operationEnd(true).
396:             */
397:            public abstract void operationEnd() throws DatabaseException;
398:
399:            /**
400:             * Different types of transactions do different things when the operation
401:             * ends. Txns do nothing, AutoTxns commit or abort, and BasicLockers and
402:             * ThreadLockers just release locks.
403:             *
404:             * @param operationOK is whether the operation succeeded, since
405:             * that may impact ending behavior. (i.e for AutoTxn)
406:             */
407:            public abstract void operationEnd(boolean operationOK)
408:                    throws DatabaseException;
409:
410:            /**
411:             * We're at the end of an operation. Move this handle lock to the
412:             * appropriate owner.
413:             */
414:            public abstract void setHandleLockOwner(boolean operationOK,
415:                    Database dbHandle, boolean dbIsClosing)
416:                    throws DatabaseException;
417:
418:            /**
419:             * A SUCCESS status equals operationOk.
420:             */
421:            public void operationEnd(OperationStatus status)
422:                    throws DatabaseException {
423:
424:                operationEnd(status == OperationStatus.SUCCESS);
425:            }
426:
427:            /**
428:             * Tell this transaction about a cursor.
429:             */
430:            public abstract void registerCursor(CursorImpl cursor)
431:                    throws DatabaseException;
432:
433:            /**
434:             * Remove a cursor from this txn.
435:             */
436:            public abstract void unRegisterCursor(CursorImpl cursor)
437:                    throws DatabaseException;
438:
439:            /*
440:             * Transactional support
441:             */
442:
443:            /**
444:             * @return the abort LSN for this node.
445:             */
446:            public abstract long getAbortLsn(long nodeId)
447:                    throws DatabaseException;
448:
449:            /**
450:             * @return the WriteLockInfo for this node.
451:             */
452:            public abstract WriteLockInfo getWriteLockInfo(long nodeId)
453:                    throws DatabaseException;
454:
455:            /**
456:             * Database operations like remove and truncate leave behind
457:             * residual DatabaseImpls that must be purged at transaction
458:             * commit or abort.
459:             */
460:            public abstract void markDeleteAtTxnEnd(DatabaseImpl db,
461:                    boolean deleteAtCommit) throws DatabaseException;
462:
463:            /**
464:             * Add delete information, to be added to the inCompressor queue
465:             * when the transaction ends.
466:             */
467:            public void addDeleteInfo(BIN bin, Key deletedKey)
468:                    throws DatabaseException {
469:
470:                synchronized (this ) {
471:                    /* Maintain only one binRef per node. */
472:                    if (deleteInfo == null) {
473:                        deleteInfo = new HashMap();
474:                    }
475:                    Long nodeId = new Long(bin.getNodeId());
476:                    BINReference binRef = (BINReference) deleteInfo.get(nodeId);
477:                    if (binRef == null) {
478:                        binRef = bin.createReference();
479:                        deleteInfo.put(nodeId, binRef);
480:                    }
481:                    binRef.addDeletedKey(deletedKey);
482:                }
483:            }
484:
485:            /*
486:             * Manage locks owned by this transaction. Note that transactions that will
487:             * be multithreaded must override these methods and provide synchronized
488:             * implementations.
489:             */
490:
491:            /**
492:             * Add a lock to set owned by this transaction.
493:             */
494:            abstract void addLock(Long nodeId, LockType type,
495:                    LockGrantType grantStatus) throws DatabaseException;
496:
497:            /**
498:             * @return true if this transaction created this node,
499:             * for a operation with transactional semantics.
500:             */
501:            public abstract boolean createdNode(long nodeId)
502:                    throws DatabaseException;
503:
504:            /**
505:             * Remove the lock from the set owned by this transaction. If specified to
506:             * LockManager.release, the lock manager will call this when its releasing
507:             * a lock.
508:             */
509:            abstract void removeLock(long nodeId) throws DatabaseException;
510:
511:            /**
512:             * A lock is being demoted. Move it from the write collection into the read
513:             * collection.
514:             */
515:            abstract void moveWriteToReadLock(long nodeId, Lock lock);
516:
517:            /**
518:             * Get lock count, for per transaction lock stats, for internal debugging.
519:             */
520:            public abstract LockStats collectStats(LockStats stats)
521:                    throws DatabaseException;
522:
523:            /*
524:             * Check txn timeout, if set. Called by the lock manager when blocking on a
525:             * lock.
526:             */
527:            public boolean isTimedOut() throws DatabaseException {
528:
529:                if (txnTimeOutMillis != 0) {
530:                    long diff = System.currentTimeMillis() - txnStartMillis;
531:                    if (diff > txnTimeOutMillis) {
532:                        return true;
533:                    }
534:                }
535:                return false;
536:            }
537:
538:            /* public for jca/ra/JELocalTransaction. */
539:            public long getTxnTimeOut() {
540:                return txnTimeOutMillis;
541:            }
542:
543:            long getTxnStartMillis() {
544:                return txnStartMillis;
545:            }
546:
547:            /**
548:             * Remove this Database from the protected Database handle set
549:             */
550:            void unregisterHandle(Database dbHandle) {
551:
552:                /*
553:                 * handleToHandleLockMap may be null if the db handle was never really
554:                 * added. This might be the case because of an unregisterHandle that
555:                 * comes from a finally clause, where the db handle was never
556:                 * successfully opened.
557:                 */
558:                if (handleToHandleLockMap != null) {
559:                    handleToHandleLockMap.remove(dbHandle);
560:                }
561:            }
562:
563:            /**
564:             * Remember how handle locks and handles match up.
565:             */
566:            public void addToHandleMaps(Long handleLockId,
567:                    Database databaseHandle) {
568:                Set dbHandleSet = null;
569:                if (handleLockToHandleMap == null) {
570:
571:                    /*
572:                     * We do lazy initialization of the maps, since they're used
573:                     * infrequently.
574:                     */
575:                    handleLockToHandleMap = new Hashtable();
576:                    handleToHandleLockMap = new Hashtable();
577:                } else {
578:                    dbHandleSet = (Set) handleLockToHandleMap.get(handleLockId);
579:                }
580:
581:                if (dbHandleSet == null) {
582:                    dbHandleSet = new HashSet();
583:                    handleLockToHandleMap.put(handleLockId, dbHandleSet);
584:                }
585:
586:                /* Map handle lockIds -> 1 or more database handles. */
587:                dbHandleSet.add(databaseHandle);
588:                /* Map database handles -> handle lock id */
589:                handleToHandleLockMap.put(databaseHandle, handleLockId);
590:            }
591:
592:            /**
593:             * @return true if this txn is willing to give up the handle lock to
594:             * another txn before this txn ends.
595:             */
596:            public boolean isHandleLockTransferrable() {
597:                return true;
598:            }
599:
600:            /**
601:             * The currentTxn passes responsiblity for this db handle lock to a txn
602:             * owned by the Database object.
603:             */
604:            void transferHandleLockToHandle(Database dbHandle)
605:                    throws DatabaseException {
606:
607:                /*
608:                 * Transfer responsiblity for this db lock from this txn to a new
609:                 * protector.
610:                 */
611:                Locker holderTxn = new BasicLocker(envImpl);
612:                transferHandleLock(dbHandle, holderTxn, true);
613:            }
614:
615:            /**
616:             *
617:             */
618:            public void transferHandleLock(Database dbHandle,
619:                    Locker destLocker, boolean demoteToRead)
620:                    throws DatabaseException {
621:
622:                /*
623:                 * Transfer responsiblity for dbHandle's handle lock from this txn to
624:                 * destLocker. If the dbHandle's databaseImpl is null, this handle
625:                 * wasn't opened successfully.
626:                 */
627:                if (DbInternal.dbGetDatabaseImpl(dbHandle) != null) {
628:                    Long handleLockId = (Long) handleToHandleLockMap
629:                            .get(dbHandle);
630:                    if (handleLockId != null) {
631:                        /* We have a handle lock for this db. */
632:                        long nodeId = handleLockId.longValue();
633:
634:                        /* Move this lock to the destination txn. */
635:                        lockManager.transfer(nodeId, this , destLocker,
636:                                demoteToRead);
637:
638:                        /*
639:                         * Make the destination txn remember that it now owns this
640:                         * handle lock.
641:                         */
642:                        destLocker.addToHandleMaps(handleLockId, dbHandle);
643:
644:                        /* Take this out of the handle lock map. */
645:                        Set dbHandleSet = (Set) handleLockToHandleMap
646:                                .get(handleLockId);
647:                        Iterator iter = dbHandleSet.iterator();
648:                        while (iter.hasNext()) {
649:                            if (((Database) iter.next()) == dbHandle) {
650:                                iter.remove();
651:                                break;
652:                            }
653:                        }
654:                        if (dbHandleSet.size() == 0) {
655:                            handleLockToHandleMap.remove(handleLockId);
656:                        }
657:
658:                        /*
659:                         * This Database must remember what txn owns it's handle lock.
660:                         */
661:                        DbInternal.dbSetHandleLocker(dbHandle, destLocker);
662:                    }
663:                }
664:            }
665:
666:            /*
667:             * Helpers
668:             */
669:            public String toString() {
670:                String className = getClass().getName();
671:                className = className.substring(className.lastIndexOf('.') + 1);
672:
673:                return Long.toString(id) + "_"
674:                        + ((thread == null) ? "" : thread.getName()) + "_"
675:                        + className;
676:            }
677:
678:            /**
679:             * Dump lock table, for debugging
680:             */
681:            public void dumpLockTable() throws DatabaseException {
682:
683:                lockManager.dump();
684:            }
685:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.