Main Page | Packages | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages

org.objectweb.cjdbc.controller.scheduler.schema.TransactionExclusiveLock Class Reference

List of all members.

Public Member Functions

boolean acquire (AbstractRequest request)
synchronized void release ()
boolean isLocked ()
long getLocker ()
ArrayList getWaitingList ()
synchronized boolean isWaiting (long transactionId)

Detailed Description

A TransactionExclusiveLock is an exclusive lock that let the owner of the lock acquire several times the lock (but it needs to be released only once). Acquire supports timeout and graceful withdrawal of timed out requests.

Author:
Emmanuel Cecchet
Version:
1.0

Definition at line 40 of file TransactionExclusiveLock.java.


Member Function Documentation

boolean org.objectweb.cjdbc.controller.scheduler.schema.TransactionExclusiveLock.acquire AbstractRequest  request  ) 
 

Acquires an exclusive lock on this table. If the lock is already held by the same transaction as the given request, this method is non-blocking else the caller is blocked until the transaction holding the lock releases it at commit/rollback time.

Parameters:
request request asking for the lock (timeout field is used and updated upon waiting)
Returns:
boolean true is the lock has been successfully acquired, false on timeout or error
See also:
release()

Definition at line 107 of file TransactionExclusiveLock.java.

References org.objectweb.cjdbc.common.sql.AbstractRequest.getTimeout(), org.objectweb.cjdbc.common.sql.AbstractRequest.getTransactionId(), org.objectweb.cjdbc.common.sql.AbstractRequest.isAutoCommit, and org.objectweb.cjdbc.common.sql.AbstractRequest.setTimeout().

00108   {
00109     long tid = request.getTransactionId();
00110 
00111     synchronized (Thread.currentThread())
00112     {
00113       WaitingListElement wle = null;
00114       synchronized (this)
00115       {
00116         if (!isLocked)
00117         { // Lock is free, take it
00118           locker = tid;
00119           isLocked = true;
00120           return true;
00121         }
00122         else
00123         {
00124           if ((!request.isAutoCommit()) && (locker == tid))
00125             return true; // We already have the lock
00126           else
00127           { // Wait for the lock
00128             wle = new WaitingListElement(Thread.currentThread(), tid);
00129             waitingList.add(wle);
00130           }
00131         }
00132       }
00133       // At this point, we have to wait for the lock.
00134       try
00135       {
00136         int timeout = request.getTimeout();
00137         if (timeout == 0)
00138         {
00139           Thread.currentThread().wait(); // No timeout
00140           // Note: isLocked and locker are already set.
00141           return true;
00142         }
00143         else
00144         { // Wait with timeout
00145           long start = System.currentTimeMillis();
00146           // Convert seconds to milliseconds for wait call
00147           long lTimeout = timeout * 1000;
00148           Thread.currentThread().wait(lTimeout);
00149           long end = System.currentTimeMillis();
00150           int remaining = (int) (lTimeout - (end - start));
00151           if (remaining > 0)
00152           { // Ok
00153             request.setTimeout(remaining);
00154             // Note: isLocked and locker are already set.
00155             return true;
00156           }
00157           else
00158           { // Too late, remove ourselves from the waiting list
00159             synchronized (this)
00160             {
00161               int idx = waitingList.indexOf(wle);
00162               if (idx == -1)
00163                 // We got the lock before being able to acquire the lock on
00164                 // this. Give the lock to the next one.
00165                 release();
00166               else
00167                 waitingList.remove(idx);
00168             }
00169             return false;
00170           }
00171         }
00172       }
00173       catch (InterruptedException ie)
00174       {
00175         synchronized (this)
00176         { // Something wrong happened, remove ourselves from the waiting list
00177           waitingList.remove(Thread.currentThread());
00178         }
00179         return false;
00180       }
00181     }
00182   }

long org.objectweb.cjdbc.controller.scheduler.schema.TransactionExclusiveLock.getLocker  ) 
 

Returns the transaction id of the lock owner. The return value is undefined if the lock is not owned (usually it is the last owner).

Returns:
int the transaction id.

Definition at line 223 of file TransactionExclusiveLock.java.

Referenced by org.objectweb.cjdbc.controller.scheduler.raidb1.RAIDb1OptimisticTransactionLevelScheduler.scheduleNonSuspendedWriteRequest().

00224   {
00225     return locker;
00226   }

ArrayList org.objectweb.cjdbc.controller.scheduler.schema.TransactionExclusiveLock.getWaitingList  ) 
 

Returns the waitingList.

Returns:
an ArrayList of WaitingListElement

Definition at line 233 of file TransactionExclusiveLock.java.

Referenced by org.objectweb.cjdbc.controller.scheduler.raidb1.RAIDb1OptimisticTransactionLevelScheduler.scheduleNonSuspendedWriteRequest().

00234   {
00235     return waitingList;
00236   }

boolean org.objectweb.cjdbc.controller.scheduler.schema.TransactionExclusiveLock.isLocked  ) 
 

Returns true if the lock is owned by someone.

Returns:
boolean value

Definition at line 212 of file TransactionExclusiveLock.java.

00213   {
00214     return isLocked;
00215   }

synchronized boolean org.objectweb.cjdbc.controller.scheduler.schema.TransactionExclusiveLock.isWaiting long  transactionId  ) 
 

Returns true if the given transaction id is contained in this lock waiting queue.

Parameters:
transactionId a transaction id
Returns:
a boolean value

Definition at line 245 of file TransactionExclusiveLock.java.

Referenced by org.objectweb.cjdbc.controller.scheduler.raidb1.RAIDb1OptimisticTransactionLevelScheduler.scheduleNonSuspendedWriteRequest().

00246   {
00247     WaitingListElement e;
00248     int size = waitingList.size();
00249     for (int i = 0; i < size; i++)
00250     {
00251       e = (WaitingListElement) waitingList.get(i);
00252       if (e.getTransactionId() == transactionId)
00253         return true;
00254     }
00255     return false;
00256   }

synchronized void org.objectweb.cjdbc.controller.scheduler.schema.TransactionExclusiveLock.release  ) 
 

Releases the lock on this table.

See also:
acquire(AbstractRequest)

Definition at line 189 of file TransactionExclusiveLock.java.

References org.objectweb.cjdbc.common.sql.AbstractRequest.getTransactionId().

Referenced by org.objectweb.cjdbc.controller.scheduler.raidb1.RAIDb1OptimisticTransactionLevelScheduler.notifyWriteCompleted().

00190   {
00191     while (!waitingList.isEmpty())
00192     {
00193       // Wake up the first waiting thread and update locker transaction id
00194       WaitingListElement e = (WaitingListElement) waitingList.remove(0);
00195       Thread thread = e.getThread();
00196       locker = e.getTransactionId();
00197       synchronized (thread)
00198       {
00199         thread.notify();
00200         // isLocked remains true
00201         return;
00202       }
00203     }
00204     isLocked = false;
00205   }


The documentation for this class was generated from the following file:
Generated on Mon Apr 11 22:04:40 2005 for C-JDBC by  doxygen 1.3.9.1