Source Code Cross Referenced for Transaction.java in  » Database-DBMS » Ozone-1.1 » org » ozoneDB » core » 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 » Database DBMS » Ozone 1.1 » org.ozoneDB.core 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        // You can redistribute this software and/or modify it under the terms of
0002:        // the Ozone Core License version 1 published by ozone-db.org.
0003:        //
0004:        // The original code and portions created by SMB are
0005:        // Copyright (C) 1997-@year@ by SMB GmbH. All rights reserved.
0006:        //
0007:        // $Id: Transaction.java,v 1.4 2002/07/26 12:29:22 per_nyfelt Exp $
0008:
0009:        package org.ozoneDB.core;
0010:
0011:        import java.io.*;
0012:        import java.util.*;
0013:        import java.lang.reflect.*;
0014:        import org.ozoneDB.DxLib.*;
0015:        import org.ozoneDB.*;
0016:        import org.ozoneDB.core.DbRemote.*;
0017:        import org.ozoneDB.core.dr.*;
0018:        import org.ozoneDB.util.*;
0019:
0020:        import org.ozoneDB.data.SimpleArrayList;
0021:
0022:        /**
0023:         * This class represents an internal transaction.<p>
0024:         *
0025:         * Most methods of this class are synchronized. In fact, this is not strictly
0026:         * needed because a transaction is invoked by one thread (associated with this
0027:         * transaction) only.<p>
0028:         *
0029:         * All public methods are wrapped into try/catch statements to convert thrown
0030:         * exception into OzoneInternalExc. So the client gets OzoneRemoteExc, if an
0031:         * object could not be found or something; OzoneInternalExc, if there was a
0032:         * critical internal error; any other exceptions were thrown by the user code.
0033:         *
0034:         *
0035:         * @author <a href="http://www.softwarebuero.de/">SMB</a>
0036:         * @author <A HREF="http://www.medium.net/">Medium.net</A>
0037:         * @version $Revision: 1.4 $Date: 2002/07/26 12:29:22 $
0038:         */
0039:        public final class Transaction implements  Locker {
0040:
0041:            /** Status of a transaction: transaction is not active. */
0042:            public final static int STATUS_NONE = 1;
0043:
0044:            /** Status of a transaction: transaction has been started. */
0045:            public final static int STATUS_STARTED = 2;
0046:
0047:            /** Status of a transaction: transaction is about to prepare. */
0048:            public final static int STATUS_PREPARING = 3;
0049:
0050:            /** Status of a transaction: transaction has been successfully prepared. */
0051:            public final static int STATUS_PREPARED = 4;
0052:
0053:            /** Status of a transaction: transaction is about to commit.*/
0054:            public final static int STATUS_COMMITING = 5;
0055:
0056:            /** Status of a transaction: transaction has been successfully committed. */
0057:            public final static int STATUS_COMMITED = 6;
0058:
0059:            /** Status of a transaction: transaction is about to abort. */
0060:            public final static int STATUS_ABORTING = 7;
0061:
0062:            /** Status of a transaction: transaction has been aborted. */
0063:            public final static int STATUS_ABORTED = 8;
0064:
0065:            public final static int HASHTABLE_INIT_SIZE = 100;
0066:
0067:            /**
0068:             * The environment of this object.
0069:             */
0070:            protected transient Env env;
0071:
0072:            protected TransactionID taID;
0073:
0074:            protected String ownerName;
0075:
0076:            protected User owner;
0077:
0078:            protected int status;
0079:
0080:            protected boolean rollbackOnly;
0081:
0082:            protected int maxLockLevel;
0083:
0084:            /**
0085:             * Data that the StoreManager implementation uses to hold data that is associated
0086:             * with this transaction. Usually this is a table of all containers that are
0087:             * currently joined to this transaction.
0088:             */
0089:            private Object data;
0090:
0091:            protected int commandCount;
0092:
0093:            /**
0094:             * The ID of the object (container) that blocks this transaction.
0095:             */
0096:            protected ObjectID blocker;
0097:
0098:            protected long startTime;
0099:
0100:            protected int acquireCount;
0101:
0102:            protected boolean stopped;
0103:
0104:            /**
0105:                Are we deadlocked?
0106:             */
0107:            protected boolean deadlocked;
0108:
0109:            /**
0110:                The minimum deadlockWaitTimeMaximum can have. (default: 1 second)
0111:             */
0112:            protected final static long deadlockWaitTimeMaximumMinimum = 1 * 1000;
0113:
0114:            /**
0115:                The maximum deadlockWaitTimeMaximum can have. (default: 30 minutes)
0116:             */
0117:            protected final static long deadlockWaitTimeMaximumMaximum = 30 * 60 * 1000;
0118:
0119:            /**
0120:                The maximum time (in milliseconds) to wait after a deadlock.
0121:             */
0122:            protected long deadlockWaitTimeMaximum;
0123:
0124:            /**
0125:                Is this thread sleeping?
0126:             */
0127:            protected boolean sleeping;
0128:
0129:            /**
0130:                The list of {@link ObjectContainer}s which are called by this transactions but where the call
0131:                is not completed. The last object called is represented by the {@link ObjectContainer} with
0132:                the greatest index in the list.
0133:             */
0134:            protected SimpleArrayList callStack;
0135:
0136:            /**
0137:             * Construct a new transaction.
0138:             *
0139:             *
0140:             * @param _env Environment of this transaction.
0141:             * @param _command Command that will be performed by run().
0142:             * @param _owner User that has started this transaction.
0143:             */
0144:            public Transaction(Env _env, User _owner) {
0145:                env = _env;
0146:                taID = new TransactionID(env.keyGenerator.nextID());
0147:                owner = _owner;
0148:
0149:                callStack = new SimpleArrayList(40);
0150:                reset();
0151:            }
0152:
0153:            /**
0154:             * Construct a new transaction. THIS TRANSACTION CAN BE USED FOR TESTING
0155:             * ONLY!
0156:             */
0157:            public Transaction(TransactionID _taID) {
0158:                taID = _taID;
0159:                reset();
0160:            }
0161:
0162:            public synchronized void stop() {
0163:                stopped = true;
0164:            }
0165:
0166:            public void reset() {
0167:                startTime = System.currentTimeMillis();
0168:                status = STATUS_STARTED;
0169:                commandCount = 0;
0170:                callStack.clear();
0171:                deadlocked = false;
0172:                setData(env.storeManager.newTransactionData());
0173:                if (deadlockWaitTimeMaximum == 0) {
0174:                    deadlockWaitTimeMaximum = deadlockWaitTimeMaximumMinimum;
0175:                }
0176:            }
0177:
0178:            protected void setDeadlockWaitTimeMaximum(long to) {
0179:                deadlockWaitTimeMaximum = to;
0180:            }
0181:
0182:            protected long getDeadlockWaitTimeMaximum() {
0183:                return deadlockWaitTimeMaximum;
0184:            }
0185:
0186:            protected long increaseDeadlockWaitTimeMaximum() {
0187:                long newDeadlockWaitTimeMaximum = (long) (getDeadlockWaitTimeMaximum() * 1.5);
0188:
0189:                if (newDeadlockWaitTimeMaximum > deadlockWaitTimeMaximumMaximum) {
0190:                    newDeadlockWaitTimeMaximum = deadlockWaitTimeMaximumMaximum;
0191:                }
0192:
0193:                setDeadlockWaitTimeMaximum(newDeadlockWaitTimeMaximum);
0194:
0195:                return newDeadlockWaitTimeMaximum;
0196:            }
0197:
0198:            public void setDeadlocked(boolean to) {
0199:                //      env.logWriter.newEntry(this,toString()+".setDeadlocked("+to+").", LogWriter.DEBUG2);
0200:                deadlocked = to;
0201:            }
0202:
0203:            public boolean isDeadlocked() {
0204:                return deadlocked;
0205:            }
0206:
0207:            public int status() {
0208:                return status;
0209:            }
0210:
0211:            public User owner() {
0212:                return owner;
0213:            }
0214:
0215:            public int maxLockLevel() {
0216:                return maxLockLevel;
0217:            }
0218:
0219:            /**
0220:                The corresponding method to {@link #acquireObjectAndPin}.
0221:                <DIV>
0222:                    Currently, it just unpins the container.
0223:                </DIV>
0224:             */
0225:            public void releaseObjectAndUnpin(ObjectContainer objectContainer) {
0226:                objectContainer.unpin();
0227:            }
0228:
0229:            /**
0230:             * Set a lock on the container specified by the given object ID and join
0231:             * the container to this transaction.
0232:             * If a container is returned, it is pinned. Thus, it has to be unpinned by the caller.
0233:             *
0234:             *
0235:             * @param id ObjectID of the container which we try to join to this transaction.
0236:             * @param lockLevel The lock level we need on this object (container).
0237:             * @return The container for the specified id, if all was ok.
0238:             * @throws ObjectNotFoundExc If there is no such object.
0239:             */
0240:            public ObjectContainer acquireObjectAndPin(ObjectID id,
0241:                    int lockLevel) throws ObjectNotFoundExc, IOException,
0242:                    ClassNotFoundException, TransactionExc, TransactionError {
0243:
0244:                // this is not good style but this method is a hotspot and we should
0245:                // do all we can to make it fast
0246:                if (env.transactionManager.exclusiveThread != null
0247:                        && env.transactionManager.exclusiveThread != Thread
0248:                                .currentThread()) {
0249:                    env.transactionManager.checkExclusion();
0250:                }
0251:
0252:                ObjectContainer container = env.storeManager
0253:                        .containerForIDAndPin(this , id);
0254:
0255:                if (container == null) {
0256:                    throw new ObjectNotFoundExc("No such object ID: " + id);
0257:                }
0258:
0259:                boolean allright = false;
0260:
0261:                try {
0262:                    container = acquireContainer(container, lockLevel);
0263:
0264:                    allright = true;
0265:
0266:                    return container;
0267:                } finally {
0268:                    if (!allright) {
0269:                        container.unpin();
0270:                    }
0271:                }
0272:            }
0273:
0274:            protected ObjectContainer acquireContainer(
0275:                    ObjectContainer container, int lockLevel)
0276:                    throws PermissionError, TransactionExc, TransactionError,
0277:                    IOException, ObjectNotFoundExc, ClassNotFoundException {
0278:
0279:                if (stopped == true) {
0280:                    throw new TransactionExc("Stopped.", TransactionExc.STOPPED);
0281:                }
0282:
0283:                maxLockLevel = lockLevel > maxLockLevel ? lockLevel
0284:                        : maxLockLevel;
0285:
0286:                acquireCount++;
0287:
0288:                // this should help to let the following code execute without
0289:                // interrupt and so ensure that the container that we retrieve from
0290:                // the store is not deactivated while this method is running
0291:                // Thread.currentThread().yield();
0292:
0293:                // transaktion als blockiert markieren (kante in lock-graphen einfuegen);
0294:                // vor deadlock-erkennung: es werden auch deadlocks mit
0295:                // transaktionen erkannt, die selber erstmal auf deadlock checken
0296:                // aber auf keinem fall zuwenige (race-cond. zwischen deadlock-pruefung
0297:                // und lock setzen)
0298:                blocker = container.id();
0299:
0300:                // this may happen when the container was deactivated between
0301:                // acquireObject() and this point; I'm not sure what to do here
0302:
0303:                // But I (Xuân Baldauf, Medium.net) am (partly):
0304:                // If our caller is acquireContainer(), the container is pinned and thus may not be deactived inbetween.
0305:                // If our caller is createObjectAndPin(), the container is pinned and thus may not be deactived inbetween.
0306:                if (container.lock() == null) {
0307:                    throw new IllegalStateException(
0308:                            "Container was wrongly deactivated. Increasing heap memory of the JVM may help.");
0309:                }
0310:
0311:                // try to aquire the lock of the container; wait until the locks is
0312:                // successfully aquired
0313:                int prevLevel = container.lock().tryAcquire(this , lockLevel);
0314:
0315:                if (prevLevel == Lock.NOT_ACQUIRED) {
0316:                    synchronized (this ) {
0317:                        while (prevLevel == Lock.NOT_ACQUIRED) {
0318:                            try {
0319:                                if (false) {
0320:                                    env.logWriter.newEntry(this , toString()
0321:                                            + " blocked by lock "
0322:                                            + container.lock() + "...",
0323:                                            LogWriter.DEBUG);
0324:                                }
0325:
0326:                                wait();
0327:
0328:                                if (false) {
0329:                                    env.logWriter.newEntry(this , toString()
0330:                                            + " checking lock again...",
0331:                                            LogWriter.DEBUG);
0332:                                }
0333:                            } catch (Exception e) {
0334:                                // do nothing; just proceed...
0335:                            }
0336:
0337:                            /*
0338:                                We have two cases:
0339:                                (1) We are called by acquireObjectAndPin()
0340:                                (2) We are not called by acquireObjectAndPin()
0341:
0342:                                In case (1), we do not need to reload, because the object is pinned.
0343:                                In case (2), we never come to this code location, because in this case, the objects are freshly created and thus never locked.
0344:
0345:                                Thus, we never need to reload.
0346:
0347:                                Oh, the reasoning above does not work out. If a cluster is pinned,
0348:                                it still may be aborted and thus need to reload. But maybe then the
0349:                                "pinned" concept is mood. Maybe pinned clusters which are arborted
0350:                                should be reloaded immediately.
0351:                             */
0352:
0353:                            // since the container was maybe deactivated while waiting we
0354:                            // reload it here again
0355:                            ObjectContainer newContainer = env.storeManager
0356:                                    .containerForIDAndPin(this , blocker);
0357:
0358:                            if (container == null) {
0359:                                throw new ObjectNotFoundExc("No such object.");
0360:                            }
0361:
0362:                            // HACK!!!
0363:                            if (!((org.ozoneDB.core.wizardStore.WizardObjectContainer) newContainer)
0364:                                    .hasSameClusterAs((org.ozoneDB.core.wizardStore.WizardObjectContainer) container)) {
0365:                                if (false) {
0366:                                    // Does this allow a pinning livelock?
0367:                                    while (container.isPinned()) {
0368:                                        newContainer.pin();
0369:                                        container.unpin();
0370:                                    }
0371:                                    newContainer.unpin();
0372:                                } else {
0373:                                    int oldPinCount = ((org.ozoneDB.core.wizardStore.WizardObjectContainer) container)
0374:                                            .getCluster().clearPinCount();
0375:
0376:                                    ((org.ozoneDB.core.wizardStore.WizardObjectContainer) newContainer)
0377:                                            .getCluster().addPinCount(
0378:                                                    oldPinCount);
0379:                                    ((org.ozoneDB.core.wizardStore.WizardObjectContainer) newContainer)
0380:                                            .getCluster().unpin();
0381:                                }
0382:
0383:                                container = newContainer;
0384:                            }
0385:
0386:                            // throw an exception if we are forced to abort because of a deadlock
0387:                            container.lock().checkDeadlock(this );
0388:
0389:                            prevLevel = container.lock().tryAcquire(this ,
0390:                                    lockLevel);
0391:                        }
0392:                    }
0393:                }
0394:
0395:                if (false) {
0396:                    env.logWriter.newEntry(this ,
0397:                            toString() + ".acquireContainer(" + blocker
0398:                                    + "): successful.", LogWriter.DEBUG);
0399:                }
0400:
0401:                // transaction is no longer blocked
0402:                blocker = null;
0403:
0404:                // after acquiring the lock we update the lock level of the container
0405:                if (prevLevel < lockLevel) {
0406:                    if (owner == null) {
0407:                        throw new PermissionError("No such user.");
0408:                    }
0409:                    if (!env.userManager.checkPermission(owner, container,
0410:                            lockLevel)) {
0411:                        throw new PermissionError(
0412:                                "User does not have proper access rights.");
0413:                    }
0414:
0415:                    env.storeManager.updateLockLevel(this , container);
0416:                }
0417:                container.touch();
0418:
0419:                return container;
0420:            }
0421:
0422:            public boolean performCommand(DbCommand command) {
0423:                if (env.logWriter.hasTarget(LogWriter.DEBUG)) {
0424:                    env.logWriter.newEntry(this , "performCommand(): "
0425:                            + toString() + ", " + command.toString(),
0426:                            LogWriter.DEBUG);
0427:                }
0428:
0429:                commandCount++;
0430:
0431:                boolean result = true;
0432:                try {
0433:                    // result goes in command.result
0434:                    command.perform(this );
0435:                } catch (TransactionError e) {
0436:                    throw e;
0437:                } catch (Throwable e) {
0438:                    Throwable resultingException = e;
0439:
0440:                    if (e instanceof  ExceptionInOzoneObjectException) {
0441:                        if (false) { // User exceptions do not need to be verbose. It's the responsibility of the user to print or not to print out the stack trace.
0442:                            Throwable cause = ((ExceptionInOzoneObjectException) e)
0443:                                    .getCause();
0444:
0445:                            env.logWriter.newEntry(this , toString()
0446:                                    + ": exception in ozone object: (" + e
0447:                                    + "): ", e, LogWriter.WARN);
0448:                            env.logWriter.newEntry(this , toString()
0449:                                    + ": cause:", cause, LogWriter.WARN);
0450:
0451:                            //                  resultingException = cause;
0452:                        }
0453:                    } else {
0454:                        env.logWriter.newEntry(this , toString()
0455:                                + ": uncaught exception: (" + e + ")", e,
0456:                                LogWriter.WARN);
0457:                    }
0458:
0459:                    if (e instanceof  PermissionError) {
0460:                        e = new PermissionDeniedExc(e.toString());
0461:                    }
0462:
0463:                    rollbackOnly = true;
0464:                    command.result = resultingException;
0465:                    result = false;
0466:                }
0467:                return result;
0468:            }
0469:
0470:            public synchronized void prepareCommit() throws IOException,
0471:                    ClassNotFoundException {
0472:                if (false && env.logWriter.hasTarget(LogWriter.DEBUG)) {
0473:                    env.logWriter.newEntry(this , "==> PREPARECOMMIT() ",
0474:                            LogWriter.DEBUG);
0475:                }
0476:                status = STATUS_PREPARING;
0477:                env.storeManager.prepareCommitTransaction(this );
0478:                status = STATUS_PREPARED;
0479:            }
0480:
0481:            /**
0482:             * Commit this transaction. The transaction has to be in PREPARED state.
0483:             * Ones this method is called it MUST commit the entire transaction
0484:             * stuff without any exception.
0485:             */
0486:            public synchronized void commit() throws IOException,
0487:                    ClassNotFoundException {
0488:                if (false && env.logWriter.hasTarget(LogWriter.DEBUG)) {
0489:                    env.logWriter.newEntry(this , "==> COMMIT() ",
0490:                            LogWriter.DEBUG);
0491:                }
0492:
0493:                status = STATUS_COMMITING;
0494:                try {
0495:                    env.storeManager.commitTransaction(this );
0496:                    // don't delete data in case of an exception
0497:                    setData(null);
0498:                } finally {
0499:                    blocker = null;
0500:                }
0501:                status = STATUS_COMMITED;
0502:            }
0503:
0504:            protected void setData(Object to) {
0505:                data = to;
0506:            }
0507:
0508:            public Object getData() {
0509:                return data;
0510:            }
0511:
0512:            /**
0513:             * Once this method is called it MUST cleanup the entire transaction
0514:             * stuff without exception. An exception signals an internal server error.
0515:             * <p>
0516:             * Note: This may be called after/from prepareCommit() !
0517:             */
0518:            public synchronized void abort(DbCommand command)
0519:                    throws IOException, ClassNotFoundException {
0520:                if (false && env.logWriter.hasTarget(LogWriter.DEBUG)) {
0521:                    env.logWriter.newEntry(this , "==> ABORT() ",
0522:                            LogWriter.DEBUG);
0523:                }
0524:
0525:                status = STATUS_ABORTING;
0526:                try {
0527:                    env.storeManager.abortTransaction(this );
0528:                } finally {
0529:                    // FIXME: We better do not delete the data now. Somewhere it is used again. (Maybe in case of deadlock retry?)
0530:                    setData(null);
0531:                    blocker = null;
0532:                }
0533:                status = STATUS_ABORTED;
0534:            }
0535:
0536:            /**
0537:             * Helper method to implement the Locker interface to support deadlock
0538:             * recognition via core.dr package
0539:             */
0540:            public Lockable blockedByAndPin() {
0541:                try {
0542:                    return blocker != null ? (Lockable) env.storeManager
0543:                            .containerForIDAndPin(this , blocker) : null;
0544:                } catch (NullPointerException e) {
0545:                    env.logWriter
0546:                            .newEntry(
0547:                                    this ,
0548:                                    "blockedBy(): Our blocker is invalidated. We are not blocked anymore?",
0549:                                    e, LogWriter.ERROR);
0550:
0551:                    blocker = null;
0552:
0553:                    return null;
0554:                } catch (Exception e) {
0555:                    env.logWriter.newEntry(this , "blockedBy() ", e,
0556:                            LogWriter.ERROR);
0557:                    throw new RuntimeException("blockedBy() FAILED!");
0558:                }
0559:            }
0560:
0561:            /**
0562:                Returns wether this locker is blocked.
0563:             */
0564:            public boolean isBlocked() {
0565:                return blocker != null;
0566:            }
0567:
0568:            /**
0569:             * Create a new database object. If the className is null, an empty container
0570:             * is created.
0571:             *
0572:             * @param className
0573:             * @param access
0574:             * @param name
0575:             * @param id The ID of the new container or null.
0576:             * @exception PermissionDeniedExc If user in invalid, name is already in
0577:             * use, target is not OzoneCompatible...
0578:             */
0579:            public ObjectContainer createObjectAndPin(String className,
0580:                    int access, String name, String sig, Object[] args,
0581:                    ObjectID id) throws Exception,
0582:                    org.ozoneDB.ExceptionInOzoneObjectException {
0583:                if (false && env.logWriter.hasTarget(LogWriter.DEBUG3)) {
0584:                    env.logWriter.newEntry(this , "createObject() ",
0585:                            LogWriter.DEBUG3);
0586:                }
0587:
0588:                // check (and wait) if a thread runs exclusively;
0589:                env.transactionManager.checkExclusion();
0590:
0591:                try {
0592:                    Class cl = null;
0593:                    if (className != null) {
0594:                        cl = env.classManager.classForName(className);
0595:                    }
0596:
0597:                    Permissions perms = new Permissions(owner, access);
0598:
0599:                    if (id == null) {
0600:                        id = new ObjectID(env.keyGenerator.nextID());
0601:                    }
0602:
0603:                    ObjectContainer container = env.storeManager
0604:                            .newContainerAndPinAndLock(this , null, id, perms,
0605:                                    Lock.LEVEL_WRITE);
0606:
0607:                    boolean alright = false;
0608:                    boolean containerAcquired = false;
0609:
0610:                    try {
0611:                        container = acquireContainer(container,
0612:                                Lock.LEVEL_WRITE);
0613:                        containerAcquired = true;
0614:
0615:                        if (cl != null) {
0616:                            container.createTarget(env, cl, sig, args);
0617:                            container.target().onCreate();
0618:                        }
0619:
0620:                        if (name != null) {
0621:                            nameObject(container.id(), name);
0622:                        }
0623:
0624:                        alright = true;
0625:
0626:                        return container;
0627:                    } finally {
0628:                        if (!containerAcquired) {
0629:                            /*
0630:                                We have had acquired a lock but somehow did not manage to acquire the corresponding container.
0631:                                Thus, the cluster would not be added to this transaction and thus it would not be unlocked
0632:                                when the transaction is finished. Thus we have to unlock it now.
0633:                             */
0634:                            container./*getCluster().getLock().*/lock()
0635:                                    .release(this );
0636:                            /*
0637:                                But is this the right behaviour? What if acquireContainer() fails for some reason (e.g. PermissionError)
0638:                                after it locked the cluster itself. Then we would unlock it while it should remain locked? Should it
0639:                                if it fails with an exception?
0640:                             */
0641:                        }
0642:                        if (!alright) {
0643:                            container.unpin();
0644:                        }
0645:                    }
0646:                } catch (InvocationTargetException e) {
0647:                    Throwable ee = e.getTargetException();
0648:
0649:                    if (ee instanceof  org.ozoneDB.core.TransactionError) {
0650:                        throw (org.ozoneDB.core.TransactionError) ee;
0651:                    }
0652:
0653:                    if (ee instanceof  ExceptionInOzoneObjectException)
0654:                        throw (ExceptionInOzoneObjectException) ee;
0655:
0656:                    throw new org.ozoneDB.ExceptionInOzoneObjectException(
0657:                            "caught", ee);
0658:                    /*
0659:                    if (ee instanceof RuntimeException) {
0660:                        throw (RuntimeException)ee;
0661:                    } else if (ee instanceof Exception) {
0662:                        throw (Exception)ee;
0663:                    } else if (ee instanceof Error) {
0664:                        throw (Error)ee;
0665:                    } else {
0666:                        throw new Exception( "Unknown exception type " + ee.getClass().getName() );
0667:                    }
0668:                     */
0669:                } catch (ExceptionInOzoneObjectException e) {
0670:                    throw e;
0671:                } catch (OzoneRemoteExc e) {
0672:                    throw e;
0673:                } catch (Exception e) {
0674:                    env.logWriter.newEntry(this , "createObject()", e,
0675:                            LogWriter.WARN);
0676:                    throw new OzoneInternalExc(e.toString(), e);
0677:                }
0678:            }
0679:
0680:            public ObjectContainer copyObjectAndPin(ObjectID id)
0681:                    throws Exception {
0682:                if (env.logWriter.hasTarget(LogWriter.DEBUG3)) {
0683:                    env.logWriter.newEntry(this , "copyObject() ",
0684:                            LogWriter.DEBUG3);
0685:                }
0686:
0687:                // check (and wait) if a thread runs exclusively;
0688:                env.transactionManager.checkExclusion();
0689:
0690:                try {
0691:                    if (env.logWriter.hasTarget(LogWriter.DEBUG3)) {
0692:                        env.logWriter.newEntry(this , "copyObject(): "
0693:                                + id.toString(), LogWriter.DEBUG3);
0694:                    }
0695:
0696:                    ObjectContainer container = acquireObjectAndPin(id,
0697:                            Lock.LEVEL_WRITE);
0698:
0699:                    try {
0700:                        Object target = container.targetClone();
0701:                        Permissions perms = (Permissions) container
0702:                                .permissions().clone();
0703:                        ObjectContainer copyContainer = env.storeManager
0704:                                .newContainerAndPinAndLock(this ,
0705:                                        (OzoneCompatible) target, new ObjectID(
0706:                                                env.keyGenerator.nextID()),
0707:                                        perms, Lock.LEVEL_WRITE);
0708:                        boolean alright = false;
0709:
0710:                        try {
0711:                            copyContainer = acquireContainer(copyContainer,
0712:                                    Lock.LEVEL_WRITE);
0713:                            alright = true;
0714:                            return copyContainer;
0715:                        } finally {
0716:                            if (!alright) {
0717:                                copyContainer.unpin();
0718:                            }
0719:                        }
0720:                    } finally {
0721:                        releaseObjectAndUnpin(container);
0722:                    }
0723:                } catch (OzoneRemoteExc e) {
0724:                    throw e;
0725:                } catch (Exception e) {
0726:                    env.logWriter.newEntry(this , "copyObject()", e,
0727:                            LogWriter.WARN);
0728:                    throw new OzoneInternalExc(e.toString(), e);
0729:                }
0730:            }
0731:
0732:            public void deleteObject(ObjectID id) throws ObjectNotFoundExc,
0733:                    IOException, ClassNotFoundException, TransactionExc,
0734:                    TransactionError, OzoneRemoteExc, OzoneInternalExc,
0735:                    ExceptionInOzoneObjectException {
0736:                if (false && env.logWriter.hasTarget(LogWriter.DEBUG3)) {
0737:                    env.logWriter.newEntry(this , "deleteObject(): "
0738:                            + id.toString(), LogWriter.DEBUG3);
0739:                }
0740:
0741:                try {
0742:                    ObjectContainer container = acquireObjectAndPin(id,
0743:                            Lock.LEVEL_WRITE);
0744:
0745:                    try {
0746:                        try {
0747:                            container.target().onDelete();
0748:                        } catch (OzoneRemoteExc e) {
0749:                            throw e;
0750:                        } catch (ExceptionInOzoneObjectException e) {
0751:                            throw e;
0752:                        } catch (Throwable e) {
0753:                            env.logWriter.newEntry(this , "deleteObject()", e,
0754:                                    LogWriter.WARN);
0755:                            //                  throw new OzoneInternalExc( e.toString() );
0756:                            throw new ExceptionInOzoneObjectException(
0757:                                    "caught onDelete()", e);
0758:                        }
0759:                        container.deleteTarget();
0760:                    } finally {
0761:                        releaseObjectAndUnpin(container);
0762:                    }
0763:                } catch (OzoneRemoteExc e) {
0764:                    throw e;
0765:                } catch (Exception e) {
0766:                    env.logWriter.newEntry(this , "deleteObject()", e,
0767:                            LogWriter.WARN);
0768:                    throw new OzoneInternalExc(e.toString(), e);
0769:                }
0770:            }
0771:
0772:            /**
0773:             * @param id
0774:             * @param methodName
0775:             * @param sig
0776:             * @param lockLevel
0777:             * @return
0778:             */
0779:            public Object invokeObject(ObjectID id, String methodName,
0780:                    String sig, Object[] args, int lockLevel) throws Exception,
0781:                    org.ozoneDB.ExceptionInOzoneObjectException {
0782:                if (false && env.logWriter.hasTarget(LogWriter.DEBUG3)) {
0783:                    env.logWriter.newEntry(this , "invokeObject(): "
0784:                            + methodName, LogWriter.DEBUG3);
0785:                }
0786:
0787:                try {
0788:                    ObjectContainer container = acquireObjectAndPin(id,
0789:                            lockLevel);
0790:
0791:                    try {
0792:                        env.getGarbageCollector().interceptInvocationPre(this ,
0793:                                container, args);
0794:
0795:                        Object result = null;
0796:
0797:                        try {
0798:                            result = container.invokeTarget(env, methodName,
0799:                                    sig, args);
0800:                        } finally {
0801:                            env.getGarbageCollector().interceptInvocationPost(
0802:                                    this , container, result);
0803:                        }
0804:
0805:                        return result;
0806:                    } finally {
0807:                        releaseObjectAndUnpin(container);
0808:                    }
0809:                    // using the container after the invoke is dangerous because
0810:                    // it's possibly deactivated meanwhile
0811:                } catch (InvocationTargetException e) {
0812:                    Throwable ee = e.getTargetException();
0813:
0814:                    if (ee instanceof  org.ozoneDB.core.TransactionError) {
0815:                        throw (org.ozoneDB.core.TransactionError) ee;
0816:                    }
0817:
0818:                    if (ee instanceof  ExceptionInOzoneObjectException)
0819:                        throw (ExceptionInOzoneObjectException) ee;
0820:
0821:                    throw new org.ozoneDB.ExceptionInOzoneObjectException(
0822:                            "caught", ee);
0823:
0824:                    /*
0825:                    if (ee instanceof RuntimeException) {
0826:                        throw (RuntimeException)ee;
0827:                    } else if (ee instanceof Exception) {
0828:                        throw (Exception)ee;
0829:                    } else if (ee instanceof Error) {
0830:                        throw (Error)ee;
0831:                    } else {
0832:                        throw new Exception( "Unknown exception type " + ee.getClass().getName() );
0833:                    }
0834:                     */
0835:                } catch (ExceptionInOzoneObjectException e) {
0836:                    throw e;
0837:                } catch (OzoneRemoteExc e) {
0838:                    env.logWriter.newEntry(this , "invokeObject()", e,
0839:                            LogWriter.WARN);
0840:                    throw e;
0841:                } catch (Exception e) {
0842:                    // since we throw away stack trace of the original exception we
0843:                    // create a new log message here
0844:                    env.logWriter.newEntry(this , "invokeObject()", e,
0845:                            LogWriter.WARN);
0846:                    throw new OzoneInternalExc(e.toString(), e);
0847:                }
0848:            }
0849:
0850:            public Object invokeObject(ObjectID id, int methodIndex,
0851:                    Object[] args, int lockLevel) throws Exception,
0852:                    org.ozoneDB.ExceptionInOzoneObjectException {
0853:                if (env.logWriter.hasTarget(LogWriter.DEBUG3)) {
0854:                    env.logWriter.newEntry(this , "invokeObject(," + methodIndex
0855:                            + "): start.", LogWriter.DEBUG3);
0856:                }
0857:
0858:                try {
0859:                    try {
0860:                        ObjectContainer container = acquireObjectAndPin(id,
0861:                                lockLevel);
0862:
0863:                        if (container == null) {
0864:                            System.out.println("***************** Null here!");
0865:                        }
0866:
0867:                        try {
0868:                            env.getGarbageCollector().interceptInvocationPre(
0869:                                    this , container, args);
0870:
0871:                            Object result = null;
0872:
0873:                            try {
0874:                                result = container.invokeTarget(env,
0875:                                        methodIndex, args);
0876:                            } finally {
0877:                                env.getGarbageCollector()
0878:                                        .interceptInvocationPost(this ,
0879:                                                container, result);
0880:                            }
0881:
0882:                            return result;
0883:                        } finally {
0884:                            releaseObjectAndUnpin(container);
0885:                        }
0886:
0887:                        // using the container after the invoke is dangerous because
0888:                        // it's possibly deactivated meanwhile
0889:                    } catch (InvocationTargetException e) {
0890:                        Throwable ee = e.getTargetException();
0891:
0892:                        if (ee instanceof  org.ozoneDB.core.TransactionError) {
0893:                            throw (org.ozoneDB.core.TransactionError) ee;
0894:                        }
0895:
0896:                        if (ee instanceof  ExceptionInOzoneObjectException)
0897:                            throw (ExceptionInOzoneObjectException) ee;
0898:
0899:                        throw new ExceptionInOzoneObjectException("caught", ee);
0900:                        /*
0901:                        if (ee instanceof RuntimeException) {
0902:                            throw (RuntimeException)ee;
0903:                        }
0904:                        else if (ee instanceof Exception) {
0905:                            throw (Exception)ee;
0906:                        }
0907:                        else if (ee instanceof Error) {
0908:                            throw (Error)ee;
0909:                        }
0910:                        else {
0911:                            throw new Exception( "Unknown exception type " + ee.getClass().getName() );
0912:                        }
0913:                         */
0914:                    } catch (ExceptionInOzoneObjectException e) {
0915:                        throw e;
0916:                    } catch (OzoneRemoteExc e) {
0917:                        env.logWriter.newEntry(this , "invokeObject()", e,
0918:                                LogWriter.WARN);
0919:                        throw e;
0920:                    } catch (Exception e) {
0921:                        // since we throw away stack trace of the original exception we
0922:                        // create a new log message here
0923:                        env.logWriter.newEntry(this , "invokeObject()", e,
0924:                                LogWriter.WARN);
0925:                        throw new OzoneInternalExc(e.toString(), e);
0926:                    }
0927:                } finally {
0928:                    if (env.logWriter.hasTarget(LogWriter.DEBUG3)) {
0929:                        env.logWriter.newEntry(this , "invokeObject(,"
0930:                                + methodIndex + "): end.", LogWriter.DEBUG3);
0931:                    }
0932:                }
0933:            }
0934:
0935:            public void nameObject(ObjectID id, String name) throws Exception {
0936:                if (false && env.logWriter.hasTarget(LogWriter.DEBUG3)) {
0937:                    env.logWriter.newEntry(this , "nameObject()",
0938:                            LogWriter.DEBUG3);
0939:                }
0940:
0941:                try {
0942:                    ObjectContainer container = acquireObjectAndPin(id,
0943:                            Lock.LEVEL_WRITE);
0944:
0945:                    try {
0946:                        ObjectContainer oldContainerWithThatName = env.storeManager
0947:                                .containerForNameAndPin(this , name);
0948:
0949:                        if (oldContainerWithThatName != null) {
0950:                            oldContainerWithThatName.unpin();
0951:                            throw new PermissionDeniedExc("Root object name '"
0952:                                    + name + "' already exists.");
0953:                        }
0954:
0955:                        env.storeManager.nameContainer(this , container, name);
0956:                    } finally {
0957:                        releaseObjectAndUnpin(container);
0958:                    }
0959:                } catch (OzoneRemoteExc e) {
0960:                    throw e;
0961:                } catch (Exception e) {
0962:                    env.logWriter.newEntry(this , "nameObject()", e,
0963:                            LogWriter.WARN);
0964:                    throw new OzoneInternalExc(e.toString(), e);
0965:                }
0966:            }
0967:
0968:            public OzoneProxy objectForName(String name) throws Exception {
0969:                if (env.logWriter.hasTarget(LogWriter.DEBUG3)) {
0970:                    env.logWriter.newEntry(this , "objectForName()",
0971:                            LogWriter.DEBUG3);
0972:                }
0973:
0974:                // check (and wait) if a thread runs exclusively;
0975:                env.transactionManager.checkExclusion();
0976:
0977:                try {
0978:                    ObjectContainer container = env.storeManager
0979:                            .containerForNameAndPin(this , name);
0980:                    if (container != null) {
0981:                        try {
0982:                            return container.ozoneProxy();
0983:                        } finally {
0984:                            container.unpin();
0985:                        }
0986:                    } else {
0987:                        return null;
0988:                    }
0989:                } catch (OzoneRemoteExc e) {
0990:                    throw e;
0991:                } catch (Exception e) {
0992:                    env.logWriter.newEntry(this , "objectForName()", e,
0993:                            LogWriter.WARN);
0994:                    throw new OzoneInternalExc(e.toString(), e);
0995:                }
0996:            }
0997:
0998:            public OzoneProxy objectForID(ObjectID id) throws Exception {
0999:                if (env.logWriter.hasTarget(LogWriter.DEBUG3)) {
1000:                    env.logWriter.newEntry(this , "objectForID()",
1001:                            LogWriter.DEBUG3);
1002:                }
1003:
1004:                // check (and wait) if a thread runs exclusively;
1005:                env.transactionManager.checkExclusion();
1006:
1007:                try {
1008:                    /*
1009:                    ObjectContainer container = env.storeManager.containerForID( this, id );
1010:                    if (container != null) {
1011:                        return container.ozoneProxy();
1012:                    } else {
1013:                        return null;
1014:                    }
1015:                     */
1016:                    ObjectContainer container = env.storeManager
1017:                            .containerForIDAndPin(this , id);
1018:                    if (container != null) {
1019:                        try {
1020:                            return container.ozoneProxy();
1021:                        } finally {
1022:                            container.unpin();
1023:                        }
1024:                    } else {
1025:                        return null;
1026:                    }
1027:                } catch (OzoneRemoteExc e) {
1028:                    throw e;
1029:                } catch (Exception e) {
1030:                    env.logWriter.newEntry(this , "objectForID()", e,
1031:                            LogWriter.WARN);
1032:                    throw new OzoneInternalExc(e.toString());
1033:                }
1034:            }
1035:
1036:            public void sleep(long millis) {
1037:                try {
1038:                    sleeping = true;
1039:
1040:                    if (false) {
1041:                        Thread.currentThread().sleep(millis);
1042:                    } else {
1043:                        synchronized (this ) {
1044:                            this .wait(millis);
1045:                        }
1046:                    }
1047:                } catch (Exception e) {
1048:                    env.logWriter.newEntry(this , "caught while sleeping", e,
1049:                            LogWriter.ERROR);
1050:                } finally {
1051:                    sleeping = false;
1052:                }
1053:            }
1054:
1055:            protected boolean isSleeping() {
1056:                return sleeping;
1057:            }
1058:
1059:            public TransactionID taID() {
1060:                return taID;
1061:            }
1062:
1063:            public boolean equals(Object obj) {
1064:                return hashCode() == obj.hashCode();
1065:            }
1066:
1067:            public String toString() {
1068:                //      return "ta[" + (byte)taID.value() + "]";
1069:                return "ta[id=" + taID + ",blocker=" + blocker + "]";
1070:            }
1071:
1072:            public void finalize() throws Throwable {
1073:                //      env.logWriter.newEntry( this, this+".finalize()", LogWriter.DEBUG );
1074:            }
1075:
1076:            public SimpleArrayList getCallStack() {
1077:                return callStack;
1078:            }
1079:
1080:            public TransactionManager getManager() {
1081:                return env.transactionManager;
1082:            }
1083:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.