Source Code Cross Referenced for LockTracker.java in  » Database-ORM » beankeeper » hu » netmind » persistence » 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 ORM » beankeeper » hu.netmind.persistence 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /**
002:         * Copyright (C) 2007 NetMind Consulting Bt.
003:         *
004:         * This library is free software; you can redistribute it and/or
005:         * modify it under the terms of the GNU Lesser General Public
006:         * License as published by the Free Software Foundation; either
007:         * version 3 of the License, or (at your option) any later version.
008:         *
009:         * This library is distributed in the hope that it will be useful,
010:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
011:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
012:         * Lesser General Public License for more details.
013:         *
014:         * You should have received a copy of the GNU Lesser General Public
015:         * License along with this library; if not, write to the Free Software
016:         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
017:         */package hu.netmind.persistence;
018:
019:        import org.apache.log4j.Logger;
020:        import java.util.*;
021:        import hu.netmind.persistence.node.RemoteLockTracker;
022:        import hu.netmind.persistence.node.LockMetaData;
023:
024:        /**
025:         * This class tracks locks on objects. Any persistable object can be locked, just like
026:         * with the <code>synchronized</code> keyword in Java, and it does roughly the same thing
027:         * too. If an object is locked, no database operations can occur outside of the lock owner
028:         * transaction. All <code>Store</code> operations automatically try to lock the objects
029:         * they work with, so there can't be any concurrent modifications.<br>
030:         * You can also lock classes or interfaces. These equal to locking database tables, only they are 
031:         * hierarchical. That means, if you lock a class, all subclasses will also be locked 
032:         * automatically. For example, if you lock <code>Object.class</code> successfully, then
033:         * only the owner of that lock will be able to modify anything. Of course, a class can't be
034:         * locked, if there is another thread which holds lock on any super-, or sub-classes, or
035:         * an instances of this class, or any subclass.
036:         * @author Brautigam Robert
037:         * @version Revision: $Revision$
038:         */
039:        public class LockTracker {
040:            private static Logger logger = Logger.getLogger(LockTracker.class);
041:
042:            private StoreContext context;
043:            private SessionInfoProvider provider;
044:
045:            public LockTracker(StoreContext context) {
046:                this .context = context;
047:                this .provider = new TransactionInfoProvider(context
048:                        .getTransactionTracker());
049:            }
050:
051:            public SessionInfoProvider getProvider() {
052:                return provider;
053:            }
054:
055:            public void setProvider(SessionInfoProvider provider) {
056:                this .provider = provider;
057:            }
058:
059:            /**
060:             * Lock a single object, and ensure that the object given is the
061:             * most recent version of the object.  The session information is gathered
062:             * from the session info provider.
063:             * @throws ConcurrentModificationException If the object is already
064:             * locked by another thread.
065:             */
066:            public void lockEnsureCurrent(Object obj) {
067:                lock(new Object[] { obj }, null, -1, true);
068:            }
069:
070:            /**
071:             * Lock a single object. The session information is gathered
072:             * from the session info provider.
073:             * @throws ConcurrentModificationException If the object is already
074:             * locked by another thread.
075:             */
076:            public void lock(Object obj) {
077:                lock(new Object[] { obj }, null, -1, false);
078:            }
079:
080:            /**
081:             * Lock a single object, and guarantee it's current. 
082:             * The session information is gathered from the session info provider.
083:             * @param obj The object to lock.
084:             * @param wait Wait the given amount of milliseconds for the lock to
085:             * free up. Method only throws ConcurrentModificationException if
086:             * the lock is not available in the given time.
087:             * @throws ConcurrentModificationException If the object is already
088:             * locked by another thread.
089:             */
090:            public void lockEnsureCurrent(Object obj, int wait) {
091:                lock(new Object[] { obj }, null, wait, true);
092:            }
093:
094:            /**
095:             * Lock a single object with wait period given. The session information is gathered
096:             * from the session info provider.
097:             * @param obj The object to lock.
098:             * @param wait Wait the given amount of milliseconds for the lock to
099:             * free up. Method only throws ConcurrentModificationException if
100:             * the lock is not available in the given time.
101:             * @throws ConcurrentModificationException If the object is already
102:             * locked by another thread.
103:             */
104:            public void lock(Object obj, int wait) {
105:                lock(new Object[] { obj }, null, wait, false);
106:            }
107:
108:            /**
109:             * Lock a single object with the session information given,
110:             * and check is the given object is the current version.
111:             * @throws ConcurrentModificationException If the object is already
112:             * locked by another thread.
113:             */
114:            public void lockEnsureCurrent(Object obj, SessionInfo info) {
115:                lock(new Object[] { obj }, info, -1, true);
116:            }
117:
118:            /**
119:             * Lock a single object with the session information given.
120:             * @throws ConcurrentModificationException If the object is already
121:             * locked by another thread.
122:             */
123:            public void lock(Object obj, SessionInfo info) {
124:                lock(new Object[] { obj }, info, -1, false);
125:            }
126:
127:            /**
128:             * Lock multiple objects, and check whether given objects
129:             * are current. The session information is gathered
130:             * from the session info provider. Use this method, if you want
131:             * to lock multiple objects at the same time.
132:             * @throws ConcurrentModificationException If the object is already
133:             * locked by another thread.
134:             */
135:            public void lockEnsureCurrent(Object[] objs) {
136:                lock(objs, null, -1, true);
137:            }
138:
139:            /**
140:             * Lock multiple objects. The session information is gathered
141:             * from the session info provider. Use this method, if you want
142:             * to lock multiple objects at the same time.
143:             * @throws ConcurrentModificationException If the object is already
144:             * locked by another thread.
145:             */
146:            public void lock(Object[] objs) {
147:                lock(objs, null, -1, false);
148:            }
149:
150:            /**
151:             * Lock multiple objects, and check whether given objects
152:             * are current. The session information is gathered
153:             * from the session info provider. Use this method, if you want
154:             * to lock multiple objects at the same time.
155:             * @param wait Wait the given amount of milliseconds for the lock to
156:             * free up. Method only throws ConcurrentModificationException if
157:             * the lock is not available in the given time.
158:             * @throws ConcurrentModificationException If the object is already
159:             * locked by another thread.
160:             */
161:            public void lockEnsureCurrent(Object[] objs, int wait) {
162:                lock(objs, null, wait, true);
163:            }
164:
165:            /**
166:             * Lock multiple objects. The session information is gathered
167:             * from the session info provider. Use this method, if you want
168:             * to lock multiple objects at the same time.
169:             * @param wait Wait the given amount of milliseconds for the lock to
170:             * free up. Method only throws ConcurrentModificationException if
171:             * the lock is not available in the given time.
172:             * @throws ConcurrentModificationException If the object is already
173:             * locked by another thread.
174:             */
175:            public void lock(Object[] objs, int wait) {
176:                lock(objs, null, wait, false);
177:            }
178:
179:            /**
180:             * Lock multiple objects with all possible parameters specified.
181:             * Use this method, if you want to lock multiple objects at the same time.
182:             * If classes are asked to be ensured to be current, the following date is
183:             * taken into account:
184:             * <ul>
185:             *    <li>If the lock is called from inside a transaction, the
186:             *    transaction's first operation's date is taken.</li>
187:             *    <li>If there are regular objects with this lock call, then
188:             *    the oldest object's read date is taken.</li>
189:             * </ul>
190:             * Whichever was earlier, the classes are checked against that date.
191:             * @param objs The object to lock simultaniously.
192:             * @param info The session info to memorize for this lock. This object will
193:             * be included in the ConcurrentModificationException.
194:             * @param wait Wait the given amount of milliseconds for the lock to
195:             * free up. Method only throws ConcurrentModificationException if
196:             * the lock is not available in the given time.
197:             * @param ensureCurrent Do the objects need to be guaranteed to be current.
198:             * If this flag is set, the lock operation will fail, if any supplied
199:             * object has a newer version.
200:             * @throws ConcurrentModificationException If the object is already
201:             * locked by another process.
202:             */
203:            public synchronized void lock(Object[] objs, SessionInfo info,
204:                    int wait, boolean ensureCurrent) {
205:                if (logger.isDebugEnabled())
206:                    logger.debug("locking " + objs.length + " objects, info: "
207:                            + info + ", wait: " + wait);
208:                // Allocate session info
209:                if (info == null) {
210:                    info = new SessionInfo(); // Empty
211:                    try {
212:                        if (provider != null)
213:                            info = provider.getSessionInfo();
214:                    } catch (Throwable e) {
215:                        logger
216:                                .warn(
217:                                        "could not allocate session info from provider",
218:                                        e);
219:                    }
220:                }
221:                // If this lock operation is inside a transacion,
222:                // then the start of the transaction will be the
223:                // date the classes (tables) are ensure to be current.
224:                // So if inside a transaction a class is asked to be
225:                // ensured actual, then it's ensured that it's not
226:                // been tampered with since the beginning of the transacion.
227:                Transaction tx = context.getTransactionTracker()
228:                        .getTransaction(TransactionTracker.TX_OPTIONAL);
229:                Long firstSerial = null;
230:                long txSerial = 0;
231:                if (tx != null) {
232:                    firstSerial = tx.getSerial();
233:                    logger
234:                            .debug("there was a transaction, classes will be compared to at least: "
235:                                    + firstSerial);
236:                    if (tx.getSerial() != null)
237:                        txSerial = tx.getSerial().longValue();
238:                }
239:                // Create metadata for all objects
240:                Vector remoteLockMetas = new Vector();
241:                for (int i = 0; i < objs.length; i++) {
242:                    LockMetaData meta = new LockMetaData();
243:                    if (objs[i] instanceof  Class) {
244:                        // Classes
245:                        meta.setObjectClass((Class) objs[i]);
246:                    } else {
247:                        // Objects
248:                        meta.setObjectClass(objs[i].getClass());
249:                        PersistenceMetaData persistenceMeta = context
250:                                .getObjectTracker().getMetaData(objs[i]);
251:                        meta.setObjectId(persistenceMeta.getPersistenceId());
252:                        meta.setQuerySerial(persistenceMeta.getQuerySerial());
253:                        meta.setStartSerial(persistenceMeta
254:                                .getPersistenceStart());
255:                        meta.setEndSerial(persistenceMeta.getPersistenceEnd());
256:                        // Check if this query serial is older than the first date current
257:                        if ((meta.getQuerySerial() != null)
258:                                && ((firstSerial == null) || (firstSerial
259:                                        .longValue() < meta.getQuerySerial()
260:                                        .longValue())))
261:                            firstSerial = meta.getQuerySerial();
262:                    }
263:                    remoteLockMetas.add(meta);
264:                }
265:                // Re-set the oldest serial to the class-only metas
266:                for (int i = 0; i < remoteLockMetas.size(); i++) {
267:                    LockMetaData meta = (LockMetaData) remoteLockMetas.get(i);
268:                    if (meta.getObjectId() == null)
269:                        meta.setQuerySerial(firstSerial);
270:                }
271:                // Now make an ordered list of the remote lock objects. It should be
272:                // ordered, because that reduces the likelyhood of a deadlock.
273:                Collections.sort(remoteLockMetas);
274:                // Lock with central lock tracker
275:                SessionInfo oldInfo = context.getNodeManager().lock(
276:                        context.getNodeManager().getNodeIndex(),
277:                        Thread.currentThread().getId(), txSerial,
278:                        remoteLockMetas, info, wait, ensureCurrent);
279:                if (oldInfo != null)
280:                    throw new ConcurrentModificationException(oldInfo, objs,
281:                            "Tried to lock, but was already locked.");
282:                // All is good in lockworld
283:                logger.debug("successful lock operation.");
284:            }
285:
286:            /**
287:             * Unlock a single object. If the object is not locked, nothing is done.
288:             */
289:            public void unlock(Object obj) {
290:                unlock(new Object[] { obj });
291:            }
292:
293:            /**
294:             * Unlock multiple objects.
295:             */
296:            public synchronized void unlock(Object[] objs) {
297:                if (logger.isDebugEnabled())
298:                    logger.debug("unlocking " + objs.length + " objects.");
299:                // The transaction if there is any
300:                Transaction tx = context.getTransactionTracker()
301:                        .getTransaction(TransactionTracker.TX_OPTIONAL);
302:                long txSerial = 0;
303:                if ((tx != null) && (tx.getSerial() != null))
304:                    txSerial = tx.getSerial().longValue();
305:                // Go through all objects and create lock metadata
306:                Vector remoteLockMetas = new Vector();
307:                for (int i = 0; i < objs.length; i++) {
308:                    LockMetaData meta = new LockMetaData();
309:                    if (objs[i] instanceof  Class) {
310:                        // Classes
311:                        meta.setObjectClass((Class) objs[i]);
312:                    } else {
313:                        // Objects
314:                        meta.setObjectClass(objs[i].getClass());
315:                        PersistenceMetaData persistenceMeta = context
316:                                .getObjectTracker().getMetaData(objs[i]);
317:                        meta.setObjectId(persistenceMeta.getPersistenceId());
318:                    }
319:                    remoteLockMetas.add(meta);
320:                }
321:                // Remote unlock
322:                try {
323:                    context.getNodeManager().unlock(
324:                            context.getNodeManager().getNodeIndex(),
325:                            Thread.currentThread().getId(), txSerial,
326:                            remoteLockMetas);
327:                } catch (Exception e) {
328:                    // Do not throw excetion here, because unlock only fails,
329:                    // if connection is severed, in which case the server will
330:                    // invalidate all locks either way.
331:                    logger.warn("could not unlock remotely", e);
332:                }
333:            }
334:
335:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.