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

org.objectweb.cjdbc.controller.scheduler.raidb1.RAIDb1OptimisticTransactionLevelScheduler Class Reference

Inheritance diagram for org.objectweb.cjdbc.controller.scheduler.raidb1.RAIDb1OptimisticTransactionLevelScheduler:

Inheritance graph
[legend]
Collaboration diagram for org.objectweb.cjdbc.controller.scheduler.raidb1.RAIDb1OptimisticTransactionLevelScheduler:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 RAIDb1OptimisticTransactionLevelScheduler ()
synchronized void setDatabaseSchema (DatabaseSchema dbs)
void mergeDatabaseSchema (DatabaseSchema dbs)
final void scheduleReadRequest (SelectRequest request) throws SQLException
final void readCompletedNotify (SelectRequest request)
void scheduleNonSuspendedWriteRequest (AbstractWriteRequest request) throws SQLException, RollbackException
final void notifyWriteCompleted (AbstractWriteRequest request)
String getXmlImpl ()

Protected Member Functions

final void commitTransaction (long transactionId)
final void rollbackTransaction (long transactionId)

Detailed Description

This scheduler provides transaction level scheduling for RAIDb-1 controllers. Each write takes a lock on the table it affects. All following writes are blocked until the transaction of the first write completes. This scheduler automatically detects simple deadlocks and rollbacks the transaction inducing the deadlock. Note that transitive deadlocks (involving more than 2 tables are not detected).

Author:
Emmanuel Cecchet
Version:
1.0

Definition at line 54 of file RAIDb1OptimisticTransactionLevelScheduler.java.


Constructor & Destructor Documentation

org.objectweb.cjdbc.controller.scheduler.raidb1.RAIDb1OptimisticTransactionLevelScheduler.RAIDb1OptimisticTransactionLevelScheduler  ) 
 

Creates a new Optimistic Transaction Level Scheduler

Definition at line 79 of file RAIDb1OptimisticTransactionLevelScheduler.java.

00080   {
00081     super(RAIDbLevels.RAIDb1, ParsingGranularities.TABLE);
00082     requestId = 0;
00083   }


Member Function Documentation

final void org.objectweb.cjdbc.controller.scheduler.raidb1.RAIDb1OptimisticTransactionLevelScheduler.commitTransaction long  transactionId  )  [protected, virtual]
 

See also:
org.objectweb.cjdbc.controller.scheduler.AbstractScheduler.commitTransaction(long)

Implements org.objectweb.cjdbc.controller.scheduler.AbstractScheduler.

Definition at line 346 of file RAIDb1OptimisticTransactionLevelScheduler.java.

00347   {
00348     releaseLocks(transactionId);
00349   }

String org.objectweb.cjdbc.controller.scheduler.raidb1.RAIDb1OptimisticTransactionLevelScheduler.getXmlImpl  )  [virtual]
 

See also:
org.objectweb.cjdbc.controller.scheduler.AbstractScheduler#getXmlImpl()

Implements org.objectweb.cjdbc.controller.scheduler.AbstractScheduler.

Definition at line 388 of file RAIDb1OptimisticTransactionLevelScheduler.java.

00389   {
00390     return "<" + DatabasesXmlTags.ELT_RAIDb1Scheduler + " "
00391         + DatabasesXmlTags.ATT_level + "=\""
00392         + DatabasesXmlTags.VAL_optimisticTransaction + "\"/>";
00393   }

void org.objectweb.cjdbc.controller.scheduler.raidb1.RAIDb1OptimisticTransactionLevelScheduler.mergeDatabaseSchema DatabaseSchema  dbs  ) 
 

Merge the given DatabaseSchema with the current one.

Parameters:
dbs a DatabaseSchema value
See also:
org.objectweb.cjdbc.controller.scheduler.schema.SchedulerDatabaseSchema

Reimplemented from org.objectweb.cjdbc.controller.scheduler.AbstractScheduler.

Definition at line 149 of file RAIDb1OptimisticTransactionLevelScheduler.java.

References org.objectweb.cjdbc.common.log.Trace.error(), and org.objectweb.cjdbc.common.log.Trace.info().

00150   {
00151     try
00152     {
00153       logger.info("Merging new database schema");
00154       schedulerDatabaseSchema.mergeSchema(new SchedulerDatabaseSchema(dbs));
00155     }
00156     catch (Exception e)
00157     {
00158       logger.error("Error while merging new database schema", e);
00159     }
00160   }

final void org.objectweb.cjdbc.controller.scheduler.raidb1.RAIDb1OptimisticTransactionLevelScheduler.notifyWriteCompleted AbstractWriteRequest  request  )  [virtual]
 

See also:
org.objectweb.cjdbc.controller.scheduler.AbstractScheduler.notifyWriteCompleted(AbstractWriteRequest)

Implements org.objectweb.cjdbc.controller.scheduler.AbstractScheduler.

Definition at line 296 of file RAIDb1OptimisticTransactionLevelScheduler.java.

References org.objectweb.cjdbc.common.log.Trace.debug(), org.objectweb.cjdbc.common.log.Trace.error(), org.objectweb.cjdbc.common.sql.AbstractRequest.getId(), org.objectweb.cjdbc.controller.scheduler.schema.SchedulerDatabaseTable.getLock(), org.objectweb.cjdbc.common.sql.AbstractWriteRequest.getTableName(), org.objectweb.cjdbc.common.sql.AbstractRequest.isAutoCommit, org.objectweb.cjdbc.common.sql.AbstractWriteRequest.isCreate(), org.objectweb.cjdbc.common.log.Trace.isDebugEnabled(), org.objectweb.cjdbc.common.sql.AbstractWriteRequest.isDrop(), and org.objectweb.cjdbc.controller.scheduler.schema.TransactionExclusiveLock.release().

00297   {
00298     if (request.isCreate())
00299     { // Add table to schema
00300       if (logger.isDebugEnabled())
00301         logger.debug("Adding table '" + request.getTableName()
00302             + "' to scheduler schema");
00303       synchronized (this)
00304       {
00305         schedulerDatabaseSchema.addTable(new SchedulerDatabaseTable(
00306             new DatabaseTable(request.getTableName())));
00307       }
00308     }
00309     else if (request.isDrop())
00310     { // Drop table from schema
00311       if (logger.isDebugEnabled())
00312         logger.debug("Removing table '" + request.getTableName()
00313             + "' to scheduler schema");
00314       synchronized (this)
00315       {
00316         schedulerDatabaseSchema.removeTable(schedulerDatabaseSchema
00317             .getTable(request.getTableName()));
00318       }
00319       return;
00320     }
00321 
00322     // Requests outside transaction delimiters must release the lock
00323     // as soon as they have executed
00324     if (request.isAutoCommit())
00325     {
00326       SchedulerDatabaseTable t = schedulerDatabaseSchema.getTable(request
00327           .getTableName());
00328       if (t == null)
00329       {
00330         String msg = "No table found to release lock for request "
00331             + request.getId();
00332         logger.error(msg);
00333       }
00334       else
00335         t.getLock().release();
00336     }
00337   }

final void org.objectweb.cjdbc.controller.scheduler.raidb1.RAIDb1OptimisticTransactionLevelScheduler.readCompletedNotify SelectRequest  request  )  [virtual]
 

See also:
org.objectweb.cjdbc.controller.scheduler.AbstractScheduler.readCompletedNotify(SelectRequest)

Implements org.objectweb.cjdbc.controller.scheduler.AbstractScheduler.

Definition at line 180 of file RAIDb1OptimisticTransactionLevelScheduler.java.

00181   {
00182   }

final void org.objectweb.cjdbc.controller.scheduler.raidb1.RAIDb1OptimisticTransactionLevelScheduler.rollbackTransaction long  transactionId  )  [protected, virtual]
 

See also:
org.objectweb.cjdbc.controller.scheduler.AbstractScheduler.rollbackTransaction(long)

Implements org.objectweb.cjdbc.controller.scheduler.AbstractScheduler.

Definition at line 354 of file RAIDb1OptimisticTransactionLevelScheduler.java.

00355   {
00356     releaseLocks(transactionId);
00357   }

void org.objectweb.cjdbc.controller.scheduler.raidb1.RAIDb1OptimisticTransactionLevelScheduler.scheduleNonSuspendedWriteRequest AbstractWriteRequest  request  )  throws SQLException, RollbackException [virtual]
 

Additionally to scheduling the request, this method replaces the SQL Date macros such as now() with the current date.

See also:
org.objectweb.cjdbc.controller.scheduler.AbstractScheduler.scheduleWriteRequest(AbstractWriteRequest)

Implements org.objectweb.cjdbc.controller.scheduler.AbstractScheduler.

Definition at line 190 of file RAIDb1OptimisticTransactionLevelScheduler.java.

References org.objectweb.cjdbc.common.log.Trace.error(), org.objectweb.cjdbc.controller.scheduler.schema.SchedulerDatabaseTable.getLock(), org.objectweb.cjdbc.controller.scheduler.schema.TransactionExclusiveLock.getLocker(), org.objectweb.cjdbc.controller.scheduler.schema.TransactionExclusiveLock.getWaitingList(), org.objectweb.cjdbc.controller.scheduler.schema.TransactionExclusiveLock.isLocked, and org.objectweb.cjdbc.controller.scheduler.schema.TransactionExclusiveLock.isWaiting().

00192   {
00193     if (request.isCreate())
00194     {
00195       synchronized (this)
00196       {
00197         request.setId(requestId++);
00198       }
00199       return;
00200     }
00201 
00202     SchedulerDatabaseTable t = schedulerDatabaseSchema.getTable(request
00203         .getTableName());
00204     if (t == null)
00205     {
00206       String msg = "No table found for request " + request.getId();
00207       logger.error(msg);
00208       throw new SQLException(msg);
00209     }
00210 
00211     // Deadlock detection
00212     TransactionExclusiveLock tableLock = t.getLock();
00213     if (!request.isAutoCommit())
00214     {
00215       synchronized (this)
00216       {
00217         if (tableLock.isLocked())
00218         { // Is the lock owner blocked by a lock we already own?
00219           long owner = tableLock.getLocker();
00220           long us = request.getTransactionId();
00221           if (owner != us)
00222           { // Parse all tables
00223             ArrayList tables = schedulerDatabaseSchema.getTables();
00224             ArrayList weAreblocking = new ArrayList();
00225             int size = tables.size();
00226             for (int i = 0; i < size; i++)
00227             {
00228               SchedulerDatabaseTable table = (SchedulerDatabaseTable) tables
00229                   .get(i);
00230               if (table == null)
00231                 continue;
00232               TransactionExclusiveLock lock = table.getLock();
00233               // Are we the lock owner ?
00234               if (lock.isLocked())
00235               {
00236                 if (lock.getLocker() == us)
00237                 {
00238                   // Is 'owner' in the list of the blocked transactions?
00239                   if (lock.isWaiting(owner))
00240                   { // Deadlock detected, we must rollback
00241                     releaseLocks(us);
00242                     throw new RollbackException(
00243                         "Deadlock detected, rollbacking transaction " + us);
00244                   }
00245                   else
00246                     weAreblocking.addAll(lock.getWaitingList());
00247                 }
00248               }
00249             }
00250           }
00251           else
00252           { // We are the lock owner and already synchronized on this
00253             // Assign the request id and exit
00254             request.setId(requestId++);
00255             return;
00256           }
00257         }
00258         else
00259         { // Lock is free, take it in the synchronized block
00260           acquireLockAndSetRequestId(request, tableLock);
00261           return;
00262         }
00263       }
00264     }
00265 
00266     acquireLockAndSetRequestId(request, tableLock);
00267   }

final void org.objectweb.cjdbc.controller.scheduler.raidb1.RAIDb1OptimisticTransactionLevelScheduler.scheduleReadRequest SelectRequest  request  )  throws SQLException [virtual]
 

Additionally to scheduling the request, this method replaces the SQL Date macros such as now() with the current date.

See also:
org.objectweb.cjdbc.controller.scheduler.AbstractScheduler.scheduleReadRequest(SelectRequest)

Implements org.objectweb.cjdbc.controller.scheduler.AbstractScheduler.

Definition at line 168 of file RAIDb1OptimisticTransactionLevelScheduler.java.

00170   {
00171     synchronized (this)
00172     {
00173       request.setId(requestId++);
00174     }
00175   }

synchronized void org.objectweb.cjdbc.controller.scheduler.raidb1.RAIDb1OptimisticTransactionLevelScheduler.setDatabaseSchema DatabaseSchema  dbs  ) 
 

Sets the DatabaseSchema of the current virtual database. This is only needed by some schedulers that will have to define their own scheduler schema

Parameters:
dbs a DatabaseSchema value
See also:
org.objectweb.cjdbc.controller.scheduler.schema.SchedulerDatabaseSchema

Reimplemented from org.objectweb.cjdbc.controller.scheduler.AbstractScheduler.

Definition at line 97 of file RAIDb1OptimisticTransactionLevelScheduler.java.

References org.objectweb.cjdbc.controller.scheduler.schema.SchedulerDatabaseTable.getName(), org.objectweb.cjdbc.common.log.Trace.info(), and org.objectweb.cjdbc.common.log.Trace.isInfoEnabled().

00098   {
00099     if (schedulerDatabaseSchema == null)
00100     {
00101       logger.info("Setting new database schema");
00102       schedulerDatabaseSchema = new SchedulerDatabaseSchema(dbs);
00103     }
00104     else
00105     { // Schema is updated, compute the diff !
00106       SchedulerDatabaseSchema newSchema = new SchedulerDatabaseSchema(dbs);
00107       ArrayList tables = schedulerDatabaseSchema.getTables();
00108       ArrayList newTables = newSchema.getTables();
00109       if (newTables == null)
00110       { // New schema is empty (no backend is active anymore)
00111         logger.info("Removing all tables.");
00112         schedulerDatabaseSchema = null;
00113         return;
00114       }
00115 
00116       // Remove extra-tables
00117       for (int i = 0; i < tables.size(); i++)
00118       {
00119         SchedulerDatabaseTable t = (SchedulerDatabaseTable) tables.get(i);
00120         if (!newSchema.hasTable(t.getName()))
00121         {
00122           schedulerDatabaseSchema.removeTable(t);
00123           if (logger.isInfoEnabled())
00124             logger.info("Removing table " + t.getName());
00125         }
00126       }
00127 
00128       // Add missing tables
00129       int size = newTables.size();
00130       for (int i = 0; i < size; i++)
00131       {
00132         SchedulerDatabaseTable t = (SchedulerDatabaseTable) newTables.get(i);
00133         if (!schedulerDatabaseSchema.hasTable(t.getName()))
00134         {
00135           schedulerDatabaseSchema.addTable(t);
00136           if (logger.isInfoEnabled())
00137             logger.info("Adding table " + t.getName());
00138         }
00139       }
00140     }
00141   }


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