org.apache.derby.iapi.services.context
Class ContextService

java.lang.Object
  extended by org.apache.derby.iapi.services.context.ContextService

public final class ContextService
extends java.lang.Object

A set of static methods to supply easier access to contexts.


Field Summary
private  java.util.HashSet allContexts
          Collection of all ContextManagers that are open in the complete Derby system.
private  HeaderPrintWriter errorStream
           
private static ContextService factory
           
private  java.lang.ThreadLocal threadContextList
          Maintains a list of all the contexts that this thread has created and/or used.
 
Constructor Summary
ContextService()
          Create a new ContextService for a Derby system.
 
Method Summary
private  boolean addToThreadList(java.lang.Thread me, ContextManager associateCM)
          The current thread (passed in a me) is setting associateCM to be its current context manager.
static Context getContext(java.lang.String contextId)
          Find the context with the given name in the context service factory loaded for the system.
static Context getContextOrNull(java.lang.String contextId)
          Find the context with the given name in the context service factory loaded for the system.
 ContextManager getCurrentContextManager()
          Get current Context Manager linked to the current Thread.
static ContextService getFactory()
           
 ContextManager newContextManager()
          It's up to the caller to track this context manager and set it in the context manager list using setCurrentContextManager.
 void notifyAllActiveThreads(Context c)
           
(package private)  void removeContext(ContextManager cm)
          Remove a ContextManager from the list of all active contexts managers.
 void resetCurrentContextManager(ContextManager cm)
          Break the link between the current Thread and the passed in ContextManager.
 void setCurrentContextManager(ContextManager cm)
          Link the current thread to the passed in Contextmanager so that a subsequent call to getCurrentContextManager by the current Thread will return cm.
static void stop()
          So it can be given to us and taken away...
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

factory

private static ContextService factory

errorStream

private HeaderPrintWriter errorStream

threadContextList

private java.lang.ThreadLocal threadContextList
Maintains a list of all the contexts that this thread has created and/or used. The object stored in the thread local varys according how this thread has been used and will be one of: This thread local is used to find the current context manager. Basically it provides fast access to a list of candidate contexts. If one of the contexts has its activeThread equal to the current thread then it is the current context manager. If the thread has pushed multiple contexts (e.g. open a new non-nested Derby connection from a server side method) then threadContextList will contain a Stack. The value for each cm will be a push order, with higher numbers being more recently pushed. To support the case where a single context manager is pushed twice (nested connection), the context manager keeps track of the number of times it has been pushed (set). Note that our synchronization requires that a single context can only be accessed by a single thread at a time. In the JDBC layer this is enforced by the synchronization on the connection object.

There are two cases we are trying to optimise.


Single thread for Connection exection.
        threadContextList.get() == cm
        // while in JDBC engine code
        cm.activeThread == Thread.currentThread();
        cm.activeCount = 1;
        

J2EE single thread for lifetime of execution.
        // thread executing request
         threadContextList.get() == cm
        // while in JDBC engine code
        cm.activeThread == Thread.currentThread();
        cm.activeCount = 1;

        // other threads that have recently executed
        // the same connection can have
        threadContextList.get() == cm
        cm.activeThread != Thread.currentThread();
       

Nested routine calls within single connection
        threadContextList.get() == cm
        // Within server-side JDBC code in a
        // function called from another function/procedure
        // called from an applications's statement
        // (three levels of nesting)
        cm.activeThread == Thread.currentThread();
        cm.activeCount = 3;         
        

Nested routine calls with the inner routine using a different connection to access a Derby database. Note nesting of orignal Contextmanager cm is changed from an activeCount of 2 to nesting within the stack once multiple ContextManagers are involved.
        threadContextList.get() == stack {cm2,cm,cm}
        cm.activeThread == Thread.currentThread();
        cm.activeCount = -1; // nesting in stack
        cm2.activeThread == Thread.currentThread();
        cm2.activeCount = -1; // nesting in stack
        

Nested multiple ContextManagers, the code supports this, though it may not be possible currently to have a stack like this from SQL/JDBC.
        threadContextList.get() == stack {cm3,cm2,cm,cm2,cm,cm}
        cm.activeThread == Thread.currentThread();
        cm.activeCount = -1; // nesting in stack
        cm2.activeThread == Thread.currentThread();
        cm2.activeCount = -1; // nesting in stack
        cm3.activeThread == Thread.currentThread();
        cm3.activeCount = -1; // nesting in stack
        


allContexts

private java.util.HashSet allContexts
Collection of all ContextManagers that are open in the complete Derby system. A ContextManager is added when it is created with newContextManager and removed when the session is closed.

See Also:
newContextManager(), SystemContext.cleanupOnError(Throwable)
Constructor Detail

ContextService

public ContextService()
Create a new ContextService for a Derby system. Only a single system is active at any time.

Method Detail

stop

public static void stop()
So it can be given to us and taken away...


getFactory

public static ContextService getFactory()

getContext

public static Context getContext(java.lang.String contextId)
Find the context with the given name in the context service factory loaded for the system.

Returns:
The requested context, null if it doesn't exist.

getContextOrNull

public static Context getContextOrNull(java.lang.String contextId)
Find the context with the given name in the context service factory loaded for the system. This version will not do any debug checking, but return null quietly if it runs into any problems.

Returns:
The requested context, null if it doesn't exist.

getCurrentContextManager

public ContextManager getCurrentContextManager()
Get current Context Manager linked to the current Thread. See setCurrentContextManager for details. Note that this call can be expensive and is only intended to be used in "stateless" situations. Ideally code has a reference to the correct ContextManager from another Object, such as a pushed Context.

Returns:
ContextManager current Context Manager

resetCurrentContextManager

public void resetCurrentContextManager(ContextManager cm)
Break the link between the current Thread and the passed in ContextManager. Called in a pair with setCurrentContextManager, see that method for details.


addToThreadList

private boolean addToThreadList(java.lang.Thread me,
                                ContextManager associateCM)
The current thread (passed in a me) is setting associateCM to be its current context manager. Sets the thread local variable threadContextList to reflect associateCM being the current ContextManager.

Returns:
True if the nesting level is to be represented in the ContextManager.activeCount field. False if not.
See Also:
ContextManager.activeCount, ContextManager.activeThread

setCurrentContextManager

public void setCurrentContextManager(ContextManager cm)
Link the current thread to the passed in Contextmanager so that a subsequent call to getCurrentContextManager by the current Thread will return cm. ContextManagers are tied to a Thread while the thread is executing Derby code. For example on most JDBC method calls the ContextManager backing the Connection object is tied to the current Thread at the start of the method and reset at the end of the method. Once the Thread has completed its Derby work the method resetCurrentContextManager must be called with the same ContextManager to break the link. Note that a subsquent use of the ContextManager may be on a separate Thread, the Thread is only linked to the ContextManager between the setCurrentContextManager and resetCurrentContextManager calls.
ContextService supports nesting of calls by a single Thread, either with the same ContextManager or a different ContextManager.


newContextManager

public ContextManager newContextManager()
It's up to the caller to track this context manager and set it in the context manager list using setCurrentContextManager. We don't keep track of it due to this call being made.


notifyAllActiveThreads

public void notifyAllActiveThreads(Context c)

removeContext

void removeContext(ContextManager cm)
Remove a ContextManager from the list of all active contexts managers.


Built on Thu 2010-12-23 20:49:13+0000, from revision ???

Apache Derby V10.6 Internals - Copyright © 2004,2007 The Apache Software Foundation. All Rights Reserved.