Source Code Cross Referenced for CurrentTransaction.java in  » JMX » je » com » sleepycat » collections » 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.collections 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*-
002:         * See the file LICENSE for redistribution information.
003:         *
004:         * Copyright (c) 2000,2008 Oracle.  All rights reserved.
005:         *
006:         * $Id: CurrentTransaction.java,v 1.46.2.5 2008/01/07 15:14:06 cwl Exp $
007:         */
008:
009:        package com.sleepycat.collections;
010:
011:        import java.lang.ref.WeakReference;
012:        import java.util.ArrayList;
013:        import java.util.List;
014:        import java.util.WeakHashMap;
015:
016:        import com.sleepycat.compat.DbCompat;
017:        import com.sleepycat.je.Cursor;
018:        import com.sleepycat.je.CursorConfig;
019:        import com.sleepycat.je.Database;
020:        import com.sleepycat.je.DatabaseException;
021:        import com.sleepycat.je.Environment;
022:        import com.sleepycat.je.EnvironmentConfig;
023:        import com.sleepycat.je.LockMode;
024:        import com.sleepycat.je.Transaction;
025:        import com.sleepycat.je.TransactionConfig;
026:        import com.sleepycat.util.RuntimeExceptionWrapper;
027:
028:        /**
029:         * Provides access to the current transaction for the current thread within the
030:         * context of a Berkeley DB environment.  This class provides explicit
031:         * transaction control beyond that provided by the {@link TransactionRunner}
032:         * class.  However, both methods of transaction control manage per-thread
033:         * transactions.
034:         *
035:         * @author Mark Hayes
036:         */
037:        public class CurrentTransaction {
038:
039:            /* For internal use, this class doubles as an Environment wrapper. */
040:
041:            private static WeakHashMap envMap = new WeakHashMap();
042:
043:            private LockMode writeLockMode;
044:            private boolean cdbMode;
045:            private boolean txnMode;
046:            private boolean lockingMode;
047:            private Environment env;
048:            private ThreadLocal localTrans = new ThreadLocal();
049:            private ThreadLocal localCdbCursors;
050:
051:            /**
052:             * Gets the CurrentTransaction accessor for a specified Berkeley DB
053:             * environment.  This method always returns the same reference when called
054:             * more than once with the same environment parameter.
055:             *
056:             * @param env is an open Berkeley DB environment.
057:             *
058:             * @return the CurrentTransaction accessor for the given environment, or
059:             * null if the environment is not transactional.
060:             */
061:            public static CurrentTransaction getInstance(Environment env) {
062:
063:                CurrentTransaction currentTxn = getInstanceInternal(env);
064:                return currentTxn.isTxnMode() ? currentTxn : null;
065:            }
066:
067:            /**
068:             * Gets the CurrentTransaction accessor for a specified Berkeley DB
069:             * environment.  Unlike getInstance(), this method never returns null.
070:             *
071:             * @param env is an open Berkeley DB environment.
072:             */
073:            static CurrentTransaction getInstanceInternal(Environment env) {
074:                synchronized (envMap) {
075:                    CurrentTransaction myEnv = null;
076:                    WeakReference myEnvRef = (WeakReference) envMap.get(env);
077:                    if (myEnvRef != null) {
078:                        myEnv = (CurrentTransaction) myEnvRef.get();
079:                    }
080:                    if (myEnv == null) {
081:                        myEnv = new CurrentTransaction(env);
082:
083:                        /*
084:                         * When a new CurrentTransaction instance is created, add
085:                         * a strong reference from the Environment to the
086:                         * CurrentTransaction instance so that it can not be GC'd
087:                         * until the Environment is GC'd (i.e. after it is closed).
088:                         * [#15721]
089:                         */
090:                        env.addReference(myEnv);
091:                        envMap.put(env, new WeakReference(myEnv));
092:                    }
093:                    return myEnv;
094:                }
095:            }
096:
097:            private CurrentTransaction(Environment env) {
098:                this .env = env;
099:                try {
100:                    EnvironmentConfig config = env.getConfig();
101:                    txnMode = config.getTransactional();
102:                    lockingMode = DbCompat.getInitializeLocking(config);
103:                    if (txnMode || lockingMode) {
104:                        writeLockMode = LockMode.RMW;
105:                    } else {
106:                        writeLockMode = LockMode.DEFAULT;
107:                    }
108:                    cdbMode = DbCompat.getInitializeCDB(config);
109:                    if (cdbMode) {
110:                        localCdbCursors = new ThreadLocal();
111:                    }
112:                } catch (DatabaseException e) {
113:                    throw new RuntimeExceptionWrapper(e);
114:                }
115:            }
116:
117:            /**
118:             * Returns whether environment is configured for locking.
119:             */
120:            final boolean isLockingMode() {
121:
122:                return lockingMode;
123:            }
124:
125:            /**
126:             * Returns whether this is a transactional environment.
127:             */
128:            final boolean isTxnMode() {
129:
130:                return txnMode;
131:            }
132:
133:            /**
134:             * Returns whether this is a Concurrent Data Store environment.
135:             */
136:            final boolean isCdbMode() {
137:
138:                return cdbMode;
139:            }
140:
141:            /**
142:             * Return the LockMode.RMW or null, depending on whether locking is
143:             * enabled.  LockMode.RMW will cause an error if passed when locking
144:             * is not enabled.  Locking is enabled if locking or transactions were
145:             * specified for this environment.
146:             */
147:            final LockMode getWriteLockMode() {
148:
149:                return writeLockMode;
150:            }
151:
152:            /**
153:             * Returns the underlying Berkeley DB environment.
154:             */
155:            public final Environment getEnvironment() {
156:
157:                return env;
158:            }
159:
160:            /**
161:             * Returns the transaction associated with the current thread for this
162:             * environment, or null if no transaction is active.
163:             */
164:            public final Transaction getTransaction() {
165:
166:                Trans trans = (Trans) localTrans.get();
167:                return (trans != null) ? trans.txn : null;
168:            }
169:
170:            /**
171:             * Returns whether auto-commit may be performed by the collections API.
172:             * True is returned if no collections API transaction is currently active,
173:             * and no XA transaction is currently active.
174:             */
175:            boolean isAutoCommitAllowed() throws DatabaseException {
176:
177:                return getTransaction() == null
178:                        && DbCompat.getThreadTransaction(env) == null;
179:            }
180:
181:            /**
182:             * Begins a new transaction for this environment and associates it with
183:             * the current thread.  If a transaction is already active for this
184:             * environment and thread, a nested transaction will be created.
185:             *
186:             * @param config the transaction configuration used for calling
187:             * {@link Environment#beginTransaction}, or null to use the default
188:             * configuration.
189:             *
190:             * @return the new transaction.
191:             *
192:             * @throws DatabaseException if the transaction cannot be started, in which
193:             * case any existing transaction is not affected.
194:             *
195:             * @throws IllegalStateException if a transaction is already active and
196:             * nested transactions are not supported by the environment.
197:             */
198:            public final Transaction beginTransaction(TransactionConfig config)
199:                    throws DatabaseException {
200:
201:                Trans trans = (Trans) localTrans.get();
202:                if (trans != null) {
203:                    if (trans.txn != null) {
204:                        if (!DbCompat.NESTED_TRANSACTIONS) {
205:                            throw new IllegalStateException(
206:                                    "Nested transactions are not supported");
207:                        }
208:                        Transaction parentTxn = trans.txn;
209:                        trans = new Trans(trans, config);
210:                        trans.txn = env.beginTransaction(parentTxn, config);
211:                        localTrans.set(trans);
212:                    } else {
213:                        trans.txn = env.beginTransaction(null, config);
214:                        trans.config = config;
215:                    }
216:                } else {
217:                    trans = new Trans(null, config);
218:                    trans.txn = env.beginTransaction(null, config);
219:                    localTrans.set(trans);
220:                }
221:                return trans.txn;
222:            }
223:
224:            /**
225:             * Commits the transaction that is active for the current thread for this
226:             * environment and makes the parent transaction (if any) the current
227:             * transaction.
228:             *
229:             * @return the parent transaction or null if the committed transaction was
230:             * not nested.
231:             *
232:             * @throws DatabaseException if an error occurs committing the transaction.
233:             * The transaction will still be closed and the parent transaction will
234:             * become the current transaction.
235:             *
236:             * @throws IllegalStateException if no transaction is active for the
237:             * current thread for this environment.
238:             */
239:            public final Transaction commitTransaction()
240:                    throws DatabaseException, IllegalStateException {
241:
242:                Trans trans = (Trans) localTrans.get();
243:                if (trans != null && trans.txn != null) {
244:                    Transaction parent = closeTxn(trans);
245:                    trans.txn.commit();
246:                    return parent;
247:                } else {
248:                    throw new IllegalStateException("No transaction is active");
249:                }
250:            }
251:
252:            /**
253:             * Aborts the transaction that is active for the current thread for this
254:             * environment and makes the parent transaction (if any) the current
255:             * transaction.
256:             *
257:             * @return the parent transaction or null if the aborted transaction was
258:             * not nested.
259:             *
260:             * @throws DatabaseException if an error occurs aborting the transaction.
261:             * The transaction will still be closed and the parent transaction will
262:             * become the current transaction.
263:             *
264:             * @throws IllegalStateException if no transaction is active for the
265:             * current thread for this environment.
266:             */
267:            public final Transaction abortTransaction()
268:                    throws DatabaseException, IllegalStateException {
269:
270:                Trans trans = (Trans) localTrans.get();
271:                if (trans != null && trans.txn != null) {
272:                    Transaction parent = closeTxn(trans);
273:                    trans.txn.abort();
274:                    return parent;
275:                } else {
276:                    throw new IllegalStateException("No transaction is active");
277:                }
278:            }
279:
280:            /**
281:             * Returns whether the current transaction is a readUncommitted
282:             * transaction.
283:             */
284:            final boolean isReadUncommitted() {
285:
286:                Trans trans = (Trans) localTrans.get();
287:                if (trans != null && trans.config != null) {
288:                    return trans.config.getReadUncommitted();
289:                } else {
290:                    return false;
291:                }
292:            }
293:
294:            private Transaction closeTxn(Trans trans) {
295:
296:                localTrans.set(trans.parent);
297:                return (trans.parent != null) ? trans.parent.txn : null;
298:            }
299:
300:            private static class Trans {
301:
302:                private Trans parent;
303:                private Transaction txn;
304:                private TransactionConfig config;
305:
306:                private Trans(Trans parent, TransactionConfig config) {
307:
308:                    this .parent = parent;
309:                    this .config = config;
310:                }
311:            }
312:
313:            /**
314:             * Opens a cursor for a given database, dup'ing an existing CDB cursor if
315:             * one is open for the current thread.
316:             */
317:            Cursor openCursor(Database db, CursorConfig cursorConfig,
318:                    boolean writeCursor, Transaction txn)
319:                    throws DatabaseException {
320:
321:                if (cdbMode) {
322:                    CdbCursors cdbCursors = null;
323:                    WeakHashMap cdbCursorsMap = (WeakHashMap) localCdbCursors
324:                            .get();
325:                    if (cdbCursorsMap == null) {
326:                        cdbCursorsMap = new WeakHashMap();
327:                        localCdbCursors.set(cdbCursorsMap);
328:                    } else {
329:                        cdbCursors = (CdbCursors) cdbCursorsMap.get(db);
330:                    }
331:                    if (cdbCursors == null) {
332:                        cdbCursors = new CdbCursors();
333:                        cdbCursorsMap.put(db, cdbCursors);
334:                    }
335:
336:                    /*
337:                     * In CDB mode the cursorConfig specified by the user is ignored
338:                     * and only the writeCursor parameter is honored.  This is the only
339:                     * meaningful cursor attribute for CDB, and here we count on
340:                     * writeCursor flag being set correctly by the caller.
341:                     */
342:                    List cursors;
343:                    CursorConfig cdbConfig;
344:                    if (writeCursor) {
345:                        if (cdbCursors.readCursors.size() > 0) {
346:
347:                            /*
348:                             * Although CDB allows opening a write cursor when a read
349:                             * cursor is open, a self-deadlock will occur if a write is
350:                             * attempted for a record that is read-locked; we should
351:                             * avoid self-deadlocks at all costs
352:                             */
353:                            throw new IllegalStateException(
354:                                    "cannot open CDB write cursor when read cursor is open");
355:                        }
356:                        cursors = cdbCursors.writeCursors;
357:                        cdbConfig = new CursorConfig();
358:                        DbCompat.setWriteCursor(cdbConfig, true);
359:                    } else {
360:                        cursors = cdbCursors.readCursors;
361:                        cdbConfig = null;
362:                    }
363:                    Cursor cursor;
364:                    if (cursors.size() > 0) {
365:                        Cursor other = ((Cursor) cursors.get(0));
366:                        cursor = other.dup(false);
367:                    } else {
368:                        cursor = db.openCursor(null, cdbConfig);
369:                    }
370:                    cursors.add(cursor);
371:                    return cursor;
372:                } else {
373:                    return db.openCursor(txn, cursorConfig);
374:                }
375:            }
376:
377:            /**
378:             * Duplicates a cursor for a given database.
379:             *
380:             * @param writeCursor true to open a write cursor in a CDB environment, and
381:             * ignored for other environments.
382:             *
383:             * @param samePosition is passed through to Cursor.dup().
384:             *
385:             * @return the open cursor.
386:             *
387:             * @throws DatabaseException if a database problem occurs.
388:             */
389:            Cursor dupCursor(Cursor cursor, boolean writeCursor,
390:                    boolean samePosition) throws DatabaseException {
391:
392:                if (cdbMode) {
393:                    WeakHashMap cdbCursorsMap = (WeakHashMap) localCdbCursors
394:                            .get();
395:                    if (cdbCursorsMap != null) {
396:                        Database db = cursor.getDatabase();
397:                        CdbCursors cdbCursors = (CdbCursors) cdbCursorsMap
398:                                .get(db);
399:                        if (cdbCursors != null) {
400:                            List cursors = writeCursor ? cdbCursors.writeCursors
401:                                    : cdbCursors.readCursors;
402:                            if (cursors.contains(cursor)) {
403:                                Cursor newCursor = cursor.dup(samePosition);
404:                                cursors.add(newCursor);
405:                                return newCursor;
406:                            }
407:                        }
408:                    }
409:                    throw new IllegalStateException("cursor to dup not tracked");
410:                } else {
411:                    return cursor.dup(samePosition);
412:                }
413:            }
414:
415:            /**
416:             * Closes a cursor.
417:             *
418:             * @param cursor the cursor to close.
419:             *
420:             * @throws DatabaseException if a database problem occurs.
421:             */
422:            void closeCursor(Cursor cursor) throws DatabaseException {
423:
424:                if (cursor == null) {
425:                    return;
426:                }
427:                if (cdbMode) {
428:                    WeakHashMap cdbCursorsMap = (WeakHashMap) localCdbCursors
429:                            .get();
430:                    if (cdbCursorsMap != null) {
431:                        Database db = cursor.getDatabase();
432:                        CdbCursors cdbCursors = (CdbCursors) cdbCursorsMap
433:                                .get(db);
434:                        if (cdbCursors != null) {
435:                            if (cdbCursors.readCursors.remove(cursor)
436:                                    || cdbCursors.writeCursors.remove(cursor)) {
437:                                cursor.close();
438:                                return;
439:                            }
440:                        }
441:                    }
442:                    throw new IllegalStateException(
443:                            "closing CDB cursor that was not known to be open");
444:                } else {
445:                    cursor.close();
446:                }
447:            }
448:
449:            /**
450:             * Returns true if a CDB cursor is open and therefore a Database write
451:             * operation should not be attempted since a self-deadlock may result.
452:             */
453:            boolean isCDBCursorOpen(Database db) throws DatabaseException {
454:
455:                if (cdbMode) {
456:                    WeakHashMap cdbCursorsMap = (WeakHashMap) localCdbCursors
457:                            .get();
458:                    if (cdbCursorsMap != null) {
459:                        CdbCursors cdbCursors = (CdbCursors) cdbCursorsMap
460:                                .get(db);
461:
462:                        if (cdbCursors != null
463:                                && (cdbCursors.readCursors.size() > 0 || cdbCursors.writeCursors
464:                                        .size() > 0)) {
465:                            return true;
466:                        }
467:                    }
468:                }
469:                return false;
470:            }
471:
472:            static final class CdbCursors {
473:
474:                List writeCursors = new ArrayList();
475:                List readCursors = new ArrayList();
476:            }
477:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.