Coverage Report - org.apache.ojb.broker.locking.LockManagerInMemoryImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
LockManagerInMemoryImpl
N/A
N/A
2.178
LockManagerInMemoryImpl$LockEntry
N/A
N/A
2.178
LockManagerInMemoryImpl$ObjectLocks
N/A
N/A
2.178
 
 1  
 package org.apache.ojb.broker.locking;
 2  
 
 3  
 /* Copyright 2002-2005 The Apache Software Foundation
 4  
  *
 5  
  * Licensed under the Apache License, Version 2.0 (the "License");
 6  
  * you may not use this file except in compliance with the License.
 7  
  * You may obtain a copy of the License at
 8  
  *
 9  
  *     http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 
 18  
 import java.io.Serializable;
 19  
 import java.util.Collection;
 20  
 import java.util.HashMap;
 21  
 import java.util.Hashtable;
 22  
 import java.util.Iterator;
 23  
 import java.util.Map;
 24  
 
 25  
 import org.apache.ojb.broker.util.logging.Logger;
 26  
 import org.apache.ojb.broker.util.logging.LoggerFactory;
 27  
 import org.apache.commons.lang.SystemUtils;
 28  
 
 29  
 /**
 30  
  * This implementation of the {@link LockManager} interface supports a simple, fast, non-blocking
 31  
  * pessimistic locking for single JVM applications.
 32  
  *
 33  
  * @version $Id: LockManagerInMemoryImpl.java,v 1.1 2007-08-24 22:17:41 ewestfal Exp $
 34  
  */
 35  
 public class LockManagerInMemoryImpl implements LockManager
 36  
 {
 37  
     private Logger log = LoggerFactory.getLogger(LockManagerInMemoryImpl.class);
 38  
     private static long CLEANUP_FREQUENCY = 1000; // 1000 milliseconds.
 39  
     private static int MAX_LOCKS_TO_CLEAN = 300;
 40  
     /**
 41  
      * MBAIRD: a LinkedHashMap returns objects in the order you put them in,
 42  
      * while still maintaining an O(1) lookup like a normal hashmap. We can then
 43  
      * use this to get the oldest entries very quickly, makes cleanup a breeze.
 44  
      */
 45  
     private HashMap locktable = new HashMap();
 46  
     private LockIsolationManager lockStrategyManager = new LockIsolationManager();
 47  
     private long m_lastCleanupAt = System.currentTimeMillis();
 48  
     private long lockTimeout;
 49  
     private long timeoutCounterRead;
 50  
     private long timeoutCounterWrite;
 51  
 
 52  
     public LockManagerInMemoryImpl()
 53  
     {
 54  
         this.lockTimeout = DEFAULT_LOCK_TIMEOUT;
 55  
     }
 56  
 
 57  
     public long getLockTimeout()
 58  
     {
 59  
         return lockTimeout;
 60  
     }
 61  
 
 62  
     public void setLockTimeout(long timeout)
 63  
     {
 64  
         this.lockTimeout = timeout;
 65  
     }
 66  
 
 67  
     /**
 68  
      * NOOP
 69  
      * @return Always '0'
 70  
      */
 71  
     public long getBlockTimeout()
 72  
     {
 73  
         return 0;
 74  
     }
 75  
 
 76  
     /**
 77  
      * NOOP
 78  
      */ 
 79  
     public void setBlockTimeout(long timeout)
 80  
     {
 81  
     }
 82  
 
 83  
     public String getLockInfo()
 84  
     {
 85  
         String eol = SystemUtils.LINE_SEPARATOR;
 86  
         StringBuffer msg = new StringBuffer("Class: " + LockManagerInMemoryImpl.class.getName() + eol);
 87  
         msg.append("lock timeout: " + getLockTimeout() + " [ms]" + eol);
 88  
         msg.append("concurrent lock owners: " + locktable.size() + eol);
 89  
         msg.append("timed out write locks: " + timeoutCounterWrite + eol);
 90  
         msg.append("timed out read locks: " + timeoutCounterRead + eol);
 91  
         return msg.toString();
 92  
     }
 93  
 
 94  
     public boolean readLock(Object key, Object resourceId, int isolationLevel)
 95  
     {
 96  
         if(log.isDebugEnabled()) log.debug("LM.readLock(tx-" + key + ", " + resourceId + ")");
 97  
         checkTimedOutLocks();
 98  
         LockEntry reader = new LockEntry(resourceId,
 99  
                 key,
 100  
                 System.currentTimeMillis(),
 101  
                 isolationLevel,
 102  
                 LockEntry.LOCK_READ);
 103  
         LockIsolation ls = lockStrategyManager.getStrategyFor(isolationLevel);
 104  
         return addReaderIfPossibleInternal(reader, ls.allowMultipleRead(), ls.allowReadWhenWrite());
 105  
     }
 106  
 
 107  
     private boolean addReaderIfPossibleInternal(LockEntry reader, boolean allowMultipleReader,
 108  
                                                 boolean allowReaderWhenWriteLock)
 109  
     {
 110  
         boolean result = false;
 111  
         ObjectLocks objectLocks = null;
 112  
         Object oid = reader.getResourceId();
 113  
         /**
 114  
          * MBAIRD: We need to synchronize the get/put so we don't have two threads
 115  
          * competing to check if something is locked and double-locking it.
 116  
          */
 117  
         synchronized(locktable)
 118  
         {
 119  
             objectLocks = (ObjectLocks) locktable.get(oid);
 120  
             if(objectLocks == null)
 121  
             {
 122  
                 // no write or read lock, go on
 123  
                 objectLocks = new ObjectLocks();
 124  
                 locktable.put(oid, objectLocks);
 125  
                 objectLocks.addReader(reader);
 126  
                 result = true;
 127  
             }
 128  
             else
 129  
             {
 130  
                 // ObjectLocks exist, first check for a write lock
 131  
                 LockEntry writer = objectLocks.getWriter();
 132  
                 if(writer != null)
 133  
                 {
 134  
                     // if writer is owned by current entity, read lock is
 135  
                     // successful (we have an write lock)
 136  
                     if(writer.isOwnedBy(reader.getKey()))
 137  
                     {
 138  
                         result = true;
 139  
                     }
 140  
                     else
 141  
                     {
 142  
                         // if read lock is allowed when different entity hold write lock
 143  
                         // go on if multiple reader allowed, else do nothing
 144  
                         if(allowReaderWhenWriteLock && allowMultipleReader)
 145  
                         {
 146  
                             objectLocks.addReader(reader);
 147  
                             result = true;
 148  
                         }
 149  
                         else
 150  
                         {
 151  
                             result = false;
 152  
                         }
 153  
                     }
 154  
                 }
 155  
                 else
 156  
                 {
 157  
                     // no write lock exist, check for existing read locks
 158  
                     if(objectLocks.getReaders().size() > 0)
 159  
                     {
 160  
                         // if we have already an read lock, do nothing
 161  
                         if(objectLocks.getReader(reader.getKey()) != null)
 162  
                         {
 163  
                             result = true;
 164  
                         }
 165  
                         else
 166  
                         {
 167  
                             // we have read locks of other entities, add read lock
 168  
                             // if allowed
 169  
                             if(allowMultipleReader)
 170  
                             {
 171  
                                 objectLocks.addReader(reader);
 172  
                                 result = true;
 173  
                             }
 174  
                         }
 175  
                     }
 176  
                     else
 177  
                     {
 178  
                         // no read locks exist, so go on
 179  
                         objectLocks.addReader(reader);
 180  
                         result = true;
 181  
                     }
 182  
                 }
 183  
             }
 184  
         }
 185  
         return result;
 186  
     }
 187  
 
 188  
     /**
 189  
      * Remove an read lock.
 190  
      */
 191  
     public boolean removeReader(Object key, Object resourceId)
 192  
     {
 193  
         boolean result = false;
 194  
         ObjectLocks objectLocks = null;
 195  
         synchronized(locktable)
 196  
         {
 197  
             objectLocks = (ObjectLocks) locktable.get(resourceId);
 198  
             if(objectLocks != null)
 199  
             {
 200  
                 /**
 201  
                  * MBAIRD, last one out, close the door and turn off the lights.
 202  
                  * if no locks (readers or writers) exist for this object, let's remove
 203  
                  * it from the locktable.
 204  
                  */
 205  
                 Map readers = objectLocks.getReaders();
 206  
                 result = readers.remove(key) != null;
 207  
                 if((objectLocks.getWriter() == null) && (readers.size() == 0))
 208  
                 {
 209  
                     locktable.remove(resourceId);
 210  
                 }
 211  
             }
 212  
         }
 213  
         return result;
 214  
     }
 215  
 
 216  
     /**
 217  
      * Remove an write lock.
 218  
      */
 219  
     public boolean removeWriter(Object key, Object resourceId)
 220  
     {
 221  
         boolean result = false;
 222  
         ObjectLocks objectLocks = null;
 223  
         synchronized(locktable)
 224  
         {
 225  
             objectLocks = (ObjectLocks) locktable.get(resourceId);
 226  
             if(objectLocks != null)
 227  
             {
 228  
                 /**
 229  
                  * MBAIRD, last one out, close the door and turn off the lights.
 230  
                  * if no locks (readers or writers) exist for this object, let's remove
 231  
                  * it from the locktable.
 232  
                  */
 233  
                 LockEntry entry = objectLocks.getWriter();
 234  
                 if(entry != null && entry.isOwnedBy(key))
 235  
                 {
 236  
                     objectLocks.setWriter(null);
 237  
                     result = true;
 238  
 
 239  
                     // no need to check if writer is null, we just set it.
 240  
                     if(objectLocks.getReaders().size() == 0)
 241  
                     {
 242  
                         locktable.remove(resourceId);
 243  
                     }
 244  
                 }
 245  
             }
 246  
         }
 247  
         return result;
 248  
     }
 249  
 
 250  
     public boolean releaseLock(Object key, Object resourceId)
 251  
     {
 252  
         if(log.isDebugEnabled()) log.debug("LM.releaseLock(tx-" + key + ", " + resourceId + ")");
 253  
         boolean result = removeReader(key, resourceId);
 254  
         // if no read lock could be removed, try write lock
 255  
         if(!result)
 256  
         {
 257  
             result = removeWriter(key, resourceId);
 258  
         }
 259  
         return result;
 260  
     }
 261  
 
 262  
     /**
 263  
      * @see LockManager#releaseLocks(Object)
 264  
      */
 265  
     public void releaseLocks(Object key)
 266  
     {
 267  
         if(log.isDebugEnabled()) log.debug("LM.releaseLocks(tx-" + key + ")");
 268  
         checkTimedOutLocks();
 269  
         releaseLocksInternal(key);
 270  
     }
 271  
 
 272  
     private void releaseLocksInternal(Object key)
 273  
     {
 274  
         synchronized(locktable)
 275  
         {
 276  
             Collection values = locktable.values();
 277  
             ObjectLocks entry;
 278  
             for(Iterator iterator = values.iterator(); iterator.hasNext();)
 279  
             {
 280  
                 entry = (ObjectLocks) iterator.next();
 281  
                 entry.removeReader(key);
 282  
                 if(entry.getWriter() != null && entry.getWriter().isOwnedBy(key))
 283  
                 {
 284  
                     entry.setWriter(null);
 285  
                 }
 286  
             }
 287  
         }
 288  
     }
 289  
 
 290  
     public boolean writeLock(Object key, Object resourceId, int isolationLevel)
 291  
     {
 292  
         if(log.isDebugEnabled()) log.debug("LM.writeLock(tx-" + key + ", " + resourceId + ")");
 293  
         checkTimedOutLocks();
 294  
         LockEntry writer = new LockEntry(resourceId,
 295  
                 key,
 296  
                 System.currentTimeMillis(),
 297  
                 isolationLevel,
 298  
                 LockEntry.LOCK_WRITE);
 299  
         LockIsolation ls = lockStrategyManager.getStrategyFor(isolationLevel);
 300  
         return setWriterIfPossibleInternal(writer, ls.allowWriteWhenRead());
 301  
     }
 302  
 
 303  
     private boolean setWriterIfPossibleInternal(LockEntry writer, boolean allowReaders)
 304  
     {
 305  
         boolean result = false;
 306  
         ObjectLocks objectLocks = null;
 307  
         /**
 308  
          * MBAIRD: We need to synchronize the get/put so we don't have two threads
 309  
          * competing to check if something is locked and double-locking it.
 310  
          */
 311  
         synchronized(locktable)
 312  
         {
 313  
             objectLocks = (ObjectLocks) locktable.get(writer.getResourceId());
 314  
             // if we don't upgrade, go on
 315  
             if(objectLocks == null)
 316  
             {
 317  
                 // no locks for current entity exist, so go on
 318  
                 objectLocks = new ObjectLocks();
 319  
                 objectLocks.setWriter(writer);
 320  
                 locktable.put(writer.getResourceId(), objectLocks);
 321  
                 result = true;
 322  
             }
 323  
             else
 324  
             {
 325  
                 // the ObjectLock exist, check if there is already a write lock
 326  
                 LockEntry oldWriter = objectLocks.getWriter();
 327  
                 if(oldWriter != null)
 328  
                 {
 329  
                     // if already a write lock exists, check owner
 330  
                     if(oldWriter.isOwnedBy(writer.getKey()))
 331  
                     {
 332  
                         // if current entity has already a write lock
 333  
                         // signal success
 334  
                         result = true;
 335  
                     }
 336  
                 }
 337  
                 else
 338  
                 {
 339  
                     // current ObjectLock has no write lock, so check for readers
 340  
                     int readerSize = objectLocks.getReaders().size();
 341  
                     if(readerSize > 0)
 342  
                     {
 343  
                         // does current entity have already an read lock
 344  
                         if(objectLocks.getReader(writer.getKey()) != null)
 345  
                         {
 346  
                             if(readerSize == 1)
 347  
                             {
 348  
                                 // only current entity has a read lock, so go on
 349  
                                 objectLocks.readers.remove(writer.getKey());
 350  
                                 objectLocks.setWriter(writer);
 351  
                                 result = true;
 352  
                             }
 353  
                             else
 354  
                             {
 355  
                                 // current entity and others have already a read lock
 356  
                                 // if aquire a write is allowed, go on
 357  
                                 if(allowReaders)
 358  
                                 {
 359  
                                     objectLocks.readers.remove(writer.getKey());
 360  
                                     objectLocks.setWriter(writer);
 361  
                                     result = true;
 362  
                                 }
 363  
                             }
 364  
                         }
 365  
                         else
 366  
                         {
 367  
                             // current entity has no read lock, but others
 368  
                             // if aquire a write is allowed, go on
 369  
                             if(allowReaders)
 370  
                             {
 371  
                                 objectLocks.setWriter(writer);
 372  
                                 result = true;
 373  
                             }
 374  
                         }
 375  
                     }
 376  
                     else
 377  
                     {
 378  
                         // no readers and writers, so go on if we don't upgrade
 379  
                         objectLocks.setWriter(writer);
 380  
                         result = true;
 381  
                     }
 382  
                 }
 383  
             }
 384  
         }
 385  
         return result;
 386  
     }
 387  
 
 388  
     public boolean upgradeLock(Object key, Object resourceId, int isolationLevel)
 389  
     {
 390  
         if(log.isDebugEnabled()) log.debug("LM.upgradeLock(tx-" + key + ", " + resourceId + ")");
 391  
         return writeLock(key, resourceId, isolationLevel);
 392  
     }
 393  
 
 394  
     /**
 395  
      * @see LockManager#hasWrite(Object, Object)
 396  
      */
 397  
     public boolean hasWrite(Object key, Object resourceId)
 398  
     {
 399  
         if(log.isDebugEnabled()) log.debug("LM.hasWrite(tx-" + key + ", " + resourceId + ")");
 400  
         checkTimedOutLocks();
 401  
         return hasWriteLockInternal(resourceId, key);
 402  
     }
 403  
 
 404  
     private boolean hasWriteLockInternal(Object resourceId, Object key)
 405  
     {
 406  
         boolean result = false;
 407  
         ObjectLocks objectLocks = null;
 408  
         synchronized(locktable)
 409  
         {
 410  
             objectLocks = (ObjectLocks) locktable.get(resourceId);
 411  
             if(objectLocks != null)
 412  
             {
 413  
                 LockEntry writer = objectLocks.getWriter();
 414  
                 if(writer != null)
 415  
                 {
 416  
                     result = writer.isOwnedBy(key);
 417  
                 }
 418  
             }
 419  
         }
 420  
         return result;
 421  
     }
 422  
 
 423  
     public boolean hasUpgrade(Object key, Object resourceId)
 424  
     {
 425  
         if(log.isDebugEnabled()) log.debug("LM.hasUpgrade(tx-" + key + ", " + resourceId + ")");
 426  
         return hasWrite(key, resourceId);
 427  
     }
 428  
 
 429  
     /**
 430  
      * @see LockManager#hasRead(Object, Object)
 431  
      */
 432  
     public boolean hasRead(Object key, Object resourceId)
 433  
     {
 434  
         if(log.isDebugEnabled()) log.debug("LM.hasRead(tx-" + key + ", " + resourceId + ')');
 435  
         checkTimedOutLocks();
 436  
         return hasReadLockInternal(resourceId, key);
 437  
     }
 438  
 
 439  
     private boolean hasReadLockInternal(Object resourceId, Object key)
 440  
     {
 441  
         boolean result = false;
 442  
         ObjectLocks objectLocks = null;
 443  
         synchronized(locktable)
 444  
         {
 445  
             objectLocks = (ObjectLocks) locktable.get(resourceId);
 446  
             if(objectLocks != null)
 447  
             {
 448  
                 LockEntry reader = objectLocks.getReader(key);
 449  
                 if(reader != null || (objectLocks.getWriter() != null && objectLocks.getWriter().isOwnedBy(key)))
 450  
                 {
 451  
                     result = true;
 452  
                 }
 453  
             }
 454  
         }
 455  
         return result;
 456  
     }
 457  
 
 458  
     /**
 459  
      *
 460  
      */
 461  
     public int lockedObjects()
 462  
     {
 463  
         return locktable.size();
 464  
     }
 465  
 
 466  
     private void checkTimedOutLocks()
 467  
     {
 468  
         if(System.currentTimeMillis() - m_lastCleanupAt > CLEANUP_FREQUENCY)
 469  
         {
 470  
             removeTimedOutLocks(getLockTimeout());
 471  
             m_lastCleanupAt = System.currentTimeMillis();
 472  
         }
 473  
     }
 474  
 
 475  
     /**
 476  
      * removes all timed out lock entries from the persistent storage.
 477  
      * The timeout value can be set in the OJB properties file.
 478  
      */
 479  
     private void removeTimedOutLocks(long timeout)
 480  
     {
 481  
         int count = 0;
 482  
         long maxAge = System.currentTimeMillis() - timeout;
 483  
         boolean breakFromLoop = false;
 484  
         ObjectLocks temp = null;
 485  
         synchronized(locktable)
 486  
         {
 487  
             Iterator it = locktable.values().iterator();
 488  
             /**
 489  
              * run this loop while:
 490  
              * - we have more in the iterator
 491  
              * - the breakFromLoop flag hasn't been set
 492  
              * - we haven't removed more than the limit for this cleaning iteration.
 493  
              */
 494  
             while(it.hasNext() && !breakFromLoop && (count <= MAX_LOCKS_TO_CLEAN))
 495  
             {
 496  
                 temp = (ObjectLocks) it.next();
 497  
                 if(temp.getWriter() != null)
 498  
                 {
 499  
                     if(temp.getWriter().getTimestamp() < maxAge)
 500  
                     {
 501  
                         // writer has timed out, set it to null
 502  
                         temp.setWriter(null);
 503  
                         ++timeoutCounterWrite;
 504  
                     }
 505  
                 }
 506  
                 if(temp.getYoungestReader() < maxAge)
 507  
                 {
 508  
                     // all readers are older than timeout.
 509  
                     temp.getReaders().clear();
 510  
                     ++timeoutCounterRead;
 511  
                     if(temp.getWriter() == null)
 512  
                     {
 513  
                         // all readers and writer are older than timeout,
 514  
                         // remove the objectLock from the iterator (which
 515  
                         // is backed by the map, so it will be removed.
 516  
                         it.remove();
 517  
                     }
 518  
                 }
 519  
                 else
 520  
                 {
 521  
                     // we need to walk each reader.
 522  
                     Iterator readerIt = temp.getReaders().values().iterator();
 523  
                     LockEntry readerLock = null;
 524  
                     while(readerIt.hasNext())
 525  
                     {
 526  
                         readerLock = (LockEntry) readerIt.next();
 527  
                         if(readerLock.getTimestamp() < maxAge)
 528  
                         {
 529  
                             // this read lock is old, remove it.
 530  
                             readerIt.remove();
 531  
                         }
 532  
                     }
 533  
                 }
 534  
                 count++;
 535  
             }
 536  
         }
 537  
     }
 538  
 
 539  
 
 540  
     //===============================================================
 541  
     // inner class
 542  
     //===============================================================
 543  
     static final class ObjectLocks
 544  
     {
 545  
         private LockEntry writer;
 546  
         private Hashtable readers;
 547  
         private long m_youngestReader = 0;
 548  
 
 549  
         ObjectLocks()
 550  
         {
 551  
             this(null);
 552  
         }
 553  
 
 554  
         ObjectLocks(LockEntry writer)
 555  
         {
 556  
             this.writer = writer;
 557  
             readers = new Hashtable();
 558  
         }
 559  
 
 560  
         LockEntry getWriter()
 561  
         {
 562  
             return writer;
 563  
         }
 564  
 
 565  
         void setWriter(LockEntry writer)
 566  
         {
 567  
             this.writer = writer;
 568  
         }
 569  
 
 570  
         Hashtable getReaders()
 571  
         {
 572  
             return readers;
 573  
         }
 574  
 
 575  
         void addReader(LockEntry reader)
 576  
         {
 577  
             /**
 578  
              * MBAIRD:
 579  
              * we want to track the youngest reader so we can remove all readers at timeout
 580  
              * if the youngestreader is older than the timeoutperiod.
 581  
              */
 582  
             if((reader.getTimestamp() < m_youngestReader) || (m_youngestReader == 0))
 583  
             {
 584  
                 m_youngestReader = reader.getTimestamp();
 585  
             }
 586  
             this.readers.put(reader.getKey(), reader);
 587  
         }
 588  
 
 589  
         long getYoungestReader()
 590  
         {
 591  
             return m_youngestReader;
 592  
         }
 593  
 
 594  
         LockEntry getReader(Object key)
 595  
         {
 596  
             return (LockEntry) this.readers.get(key);
 597  
         }
 598  
 
 599  
         LockEntry removeReader(Object key)
 600  
         {
 601  
             return (LockEntry) this.readers.remove(key);
 602  
         }
 603  
     }
 604  
 
 605  
 
 606  
     //===============================================================
 607  
     // inner class
 608  
     //===============================================================
 609  
     /**
 610  
      * A lock entry encapsulates locking information.
 611  
      */
 612  
     final class LockEntry implements Serializable
 613  
     {
 614  
         /**
 615  
          * marks a Read Lock.
 616  
          */
 617  
         static final int LOCK_READ = 0;
 618  
 
 619  
         /**
 620  
          * marks a Write Lock.
 621  
          */
 622  
         static final int LOCK_WRITE = 1;
 623  
 
 624  
         /**
 625  
          * the object to be locked.
 626  
          */
 627  
         private Object resourceId;
 628  
 
 629  
         /**
 630  
          * key for locked object
 631  
          */
 632  
         private Object key;
 633  
 
 634  
         /**
 635  
          * the timestamp marking the time of acquisition of this lock
 636  
          */
 637  
         private long timestamp;
 638  
 
 639  
         /**
 640  
          * the isolationlevel for this lock.
 641  
          */
 642  
         private int isolationLevel;
 643  
 
 644  
         /**
 645  
          * marks if this is a read or a write lock.
 646  
          * LOCK_READ = 0;
 647  
          * LOCK_WRITE = 1;
 648  
          */
 649  
         private int lockType;
 650  
 
 651  
         /**
 652  
          * Multiargument constructor for fast loading of LockEntries by OJB.
 653  
          */
 654  
         public LockEntry(Object resourceId,
 655  
                          Object key,
 656  
                          long timestamp,
 657  
                          int isolationLevel,
 658  
                          int lockType)
 659  
         {
 660  
             this.resourceId = resourceId;
 661  
             this.key = key;
 662  
             this.timestamp = timestamp;
 663  
             this.isolationLevel = isolationLevel;
 664  
             this.lockType = lockType;
 665  
 
 666  
         }
 667  
 
 668  
         /**
 669  
          * Returns the resource id of the locked object (or the locked object itself).
 670  
          */
 671  
         public Object getResourceId()
 672  
         {
 673  
             return resourceId;
 674  
         }
 675  
 
 676  
         /**
 677  
          * Returns lock key.
 678  
          */
 679  
         public Object getKey()
 680  
         {
 681  
             return key;
 682  
         }
 683  
 
 684  
         /**
 685  
          * returns the timestamp of the acqusition of the lock.
 686  
          */
 687  
         public long getTimestamp()
 688  
         {
 689  
             return timestamp;
 690  
         }
 691  
 
 692  
         /**
 693  
          * returns the isolation level of this lock
 694  
          */
 695  
         public int getIsolationLevel()
 696  
         {
 697  
             return isolationLevel;
 698  
         }
 699  
 
 700  
         /**
 701  
          * returns the locktype of this lock.
 702  
          *
 703  
          * @return LOCK_READ if lock is a readlock,
 704  
          *         LOCK_WRITE if lock is a Write lock.
 705  
          */
 706  
         public int getLockType()
 707  
         {
 708  
             return lockType;
 709  
         }
 710  
 
 711  
         /**
 712  
          * sets the locktype of this lockentry.
 713  
          *
 714  
          * @param locktype LOCK_READ for read, LOCK_WRITE for write lock.
 715  
          */
 716  
         public void setLockType(int locktype)
 717  
         {
 718  
             this.lockType = locktype;
 719  
         }
 720  
 
 721  
         /**
 722  
          * Returns true if this lock is owned by the specified key.
 723  
          */
 724  
         public boolean isOwnedBy(Object key)
 725  
         {
 726  
             return this.getKey().equals(key);
 727  
         }
 728  
 
 729  
 
 730  
         /**
 731  
          * Sets the isolationLevel.
 732  
          *
 733  
          * @param isolationLevel The isolationLevel to set
 734  
          */
 735  
         public void setIsolationLevel(int isolationLevel)
 736  
         {
 737  
             this.isolationLevel = isolationLevel;
 738  
         }
 739  
 
 740  
         /**
 741  
          * Sets the resourceId.
 742  
          *
 743  
          * @param resourceId The resourceId to set
 744  
          */
 745  
         public void setresourceId(String resourceId)
 746  
         {
 747  
             this.resourceId = resourceId;
 748  
         }
 749  
 
 750  
         /**
 751  
          * Sets the timestamp.
 752  
          *
 753  
          * @param timestamp The timestamp to set
 754  
          */
 755  
         public void setTimestamp(long timestamp)
 756  
         {
 757  
             this.timestamp = timestamp;
 758  
         }
 759  
 
 760  
         /**
 761  
          * Sets the key.
 762  
          *
 763  
          * @param key The key to set
 764  
          */
 765  
         public void setKey(Object key)
 766  
         {
 767  
             this.key = key;
 768  
         }
 769  
     }
 770  
 }