ServerSessionpublic class ServerSession extends DatabaseSessionImpl implements ServerImplementation of Server
INTERNAL:
The public interface should be used.
Purpose: A single session that supports multiple user/clients connection at the same time.
Description: This session supports a shared session that can be used by multiple users
or clients in a three-tiered application. It brokers client sessions to allow read and write access
through a unified object cache. The server session provides a shared read only database connection that
is used by all of its client for reads. All changes to objects and the database must be done through
a unit of work acquired from the client session, this allows the changes to occur in a transactional object
space and under a exclusive database connection.
Responsibilities:
- Connecting/disconnecting the default reading login.
- Reading objects and maintaining the object cache.
- Brokering client sessions.
- Disabling database modification through the shared connection.
|
Fields Summary |
---|
protected ConnectionPool | readConnectionPool | protected Map | connectionPools | protected ConnectionPolicy | defaultConnectionPolicy | protected int | maxNumberOfNonPooledConnections | protected int | numberOfNonPooledConnectionsUsed | public static final int | MAX_WRITE_CONNECTIONS | public static final int | MIN_WRITE_CONNECTIONS |
Constructors Summary |
---|
public ServerSession()INTERNAL:
Create and return a new default server session.
Used for EJB SessionManager to instantiate a server session
super();
this.connectionPools = new HashMap(10);
| public ServerSession(Project project, ConnectionPolicy defaultConnectionPolicy, Login readLogin)PUBLIC:
Create and return a new server session.
Configure the default connection policy to be used.
This policy is used on the "acquireClientSession()" protocol.
Use the readLogin, if specified, for logging into the read
connection pool.
super(project);
this.connectionPools = new HashMap(10);
this.defaultConnectionPolicy = defaultConnectionPolicy;
this.maxNumberOfNonPooledConnections = 50;
this.numberOfNonPooledConnectionsUsed = 0;
Login login = (readLogin != null) ? readLogin : project.getDatasourceLogin();
setReadConnectionPool(login);
| public ServerSession(Project project, ConnectionPolicy defaultConnectionPolicy, Login readLogin, Login sequenceLogin)PUBLIC:
Create and return a new server session.
Configure the default connection policy to be used.
This policy is used on the "acquireClientSession()" protocol.
Use the readLogin, if specified, for logging into the read
connection pool.
Use the sequenceLogin, if specified, for creating a connection pool
to be used by sequencing through SequencingConnectionHandler
sequenceLogin *MUST*:
1. specify *NON-JTS* connections (such as NON_JTS driver or read-only datasource);
2. sequenceLogin.shouldUseExternalTransactionController()==false
this(project, defaultConnectionPolicy, readLogin);
if (sequenceLogin != null) {
//** sequencing refactoring
getSequencingControl().setShouldUseSeparateConnection(true);
getSequencingControl().setLogin(sequenceLogin);
}
| public ServerSession(Login login)PUBLIC:
Create and return a new server session.
By giving the login information on creation this allows the session to initialize itself
to the platform given in the login. This constructor does not return a connected session.
To connect the session to the database login() must be sent to it. The login(userName, password)
method may also be used to connect the session, this allows for the user name and password
to be given at login but for the other database information to be provided when the session is created.
By default the server session uses a default connection pool with 5 min 10 max number of connections
and a max number 50 non-pooled connections allowed.
this(new oracle.toplink.essentials.sessions.Project(login));
| public ServerSession(Login login, int minNumberOfPooledConnection, int maxNumberOfPooledConnection)PUBLIC:
Create and return a new server session.
Configure the min and max number of connections for the default pool.
this(new oracle.toplink.essentials.sessions.Project(login), minNumberOfPooledConnection, maxNumberOfPooledConnection);
| public ServerSession(Login login, ConnectionPolicy defaultConnectionPolicy)PUBLIC:
Create and return a new server session.
Configure the default connection policy to be used.
This policy is used on the "acquireClientSession()" protocol.
this(new oracle.toplink.essentials.sessions.Project(login), defaultConnectionPolicy);
| public ServerSession(Project project)PUBLIC:
Create and return a new server session.
By giving the project information on creation this allows the session to initialize itself
to the platform given in the login. This constructor does not return a connected session.
To connect the session to the database login() must be sent to it. The login(userName, password)
method may also be used to connect the session, this allows for the user name and password
to be given at login but for the other database information to be provided when the session is created.
By default the server session uses a default connection pool with 5 min 10 max number of connections
and a max number 50 non-pooled connections allowed.
this(project, MIN_WRITE_CONNECTIONS, MAX_WRITE_CONNECTIONS);
| public ServerSession(Project project, int minNumberOfPooledConnection, int maxNumberOfPooledConnection)PUBLIC:
Create and return a new server session.
Configure the min and max number of connections for the default pool.
this(project, new ConnectionPolicy("default"));
ConnectionPool pool = null;
if (project.getDatasourceLogin().shouldUseExternalConnectionPooling()) {
pool = new ExternalConnectionPool("default", project.getDatasourceLogin(), this);
} else {
pool = new ConnectionPool("default", project.getDatasourceLogin(), minNumberOfPooledConnection, maxNumberOfPooledConnection, this);
}
this.connectionPools.put("default", pool);
| public ServerSession(Project project, int minNumberOfPooledConnection, int maxNumberOfPooledConnection, Login readLogin)PUBLIC:
Create and return a new server session.
Configure the min and max number of connections for the default pool.
Use the login from the project for the write pool. Use the passed
in login for the read pool, if specified, or the project login if not.
this(project, new ConnectionPolicy("default"), readLogin);
ConnectionPool pool = null;
if (project.getDatasourceLogin().shouldUseExternalConnectionPooling()) {
pool = new ExternalConnectionPool("default", project.getDatasourceLogin(), this);
} else {
pool = new ConnectionPool("default", project.getDatasourceLogin(), minNumberOfPooledConnection, maxNumberOfPooledConnection, this);
}
this.connectionPools.put("default", pool);
| public ServerSession(Project project, int minNumberOfPooledConnection, int maxNumberOfPooledConnection, Login readLogin, Login sequenceLogin)PUBLIC:
Create and return a new server session.
Configure the min and max number of connections for the default pool.
Use the login from the project for the write pool. Use the passed
in login for the read pool, if specified, or the project login if not.
Use the sequenceLogin, if specified, for creating a connection pool
to be used by sequencing through SequencingConnectionHandler
sequenceLogin *MUST*:
1. specify *NON-JTS* connections (such as NON_JTS driver or read-only datasource);
2. sequenceLogin.shouldUseExternalTransactionController()==false
this(project, new ConnectionPolicy("default"), readLogin, sequenceLogin);
ConnectionPool pool = null;
if (project.getDatasourceLogin().shouldUseExternalConnectionPooling()) {
pool = new ExternalConnectionPool("default", project.getDatasourceLogin(), this);
} else {
pool = new ConnectionPool("default", project.getDatasourceLogin(), minNumberOfPooledConnection, maxNumberOfPooledConnection, this);
}
this.connectionPools.put("default", pool);
| public ServerSession(Project project, ConnectionPolicy defaultConnectionPolicy)PUBLIC:
Create and return a new server session.
Configure the default connection policy to be used.
This policy is used on the "acquireClientSession()" protocol.
super(project);
this.connectionPools = new HashMap(10);
this.defaultConnectionPolicy = defaultConnectionPolicy;
this.maxNumberOfNonPooledConnections = 50;
this.numberOfNonPooledConnectionsUsed = 0;
setReadConnectionPool(project.getDatasourceLogin());
|
Methods Summary |
---|
public void | acquireClientConnection(oracle.toplink.essentials.threetier.ClientSession clientSession)INTERNAL:
Allocate the client's connection resource.
if (clientSession.getConnectionPolicy().isPooled()) {
ConnectionPool pool = (ConnectionPool)getConnectionPools().get(clientSession.getConnectionPolicy().getPoolName());
Accessor connection = pool.acquireConnection();
clientSession.setWriteConnection(connection);
getEventManager().postAcquireConnection(connection);
} else {
// This method is synchronized, so while is not required, only if.
synchronized (this) {
while (getNumberOfNonPooledConnectionsUsed() >= getMaxNumberOfNonPooledConnections()) {
try {
wait();// Notify is called when connections are released.
} catch (InterruptedException exception) {
throw ConcurrencyException.waitFailureOnServerSession(exception);
}
}
setNumberOfNonPooledConnectionsUsed(getNumberOfNonPooledConnectionsUsed() + 1);
clientSession.setWriteConnection(clientSession.getLogin().buildAccessor());
clientSession.connect();
}
}
| public oracle.toplink.essentials.threetier.ClientSession | acquireClientSession()PUBLIC:
Return a client session for this server session.
Each user/client connected to this server session must acquire there own client session
to communicate to the server through.
This method allows for a client session to be acquired sharing the same login as the server session.
return acquireClientSession((ConnectionPolicy)getDefaultConnectionPolicy().clone());
| public oracle.toplink.essentials.threetier.ClientSession | acquireClientSession(java.lang.String poolName)PUBLIC:
Return a client session for this server session.
Each user/client connected to this server session must acquire there own client session
to communicate to the server through.
This method allows for a client session to be acquired sharing its connection from a pool
of connection allocated on the server session.
By default this uses a lazy connection policy.
return acquireClientSession(new ConnectionPolicy(poolName));
| public oracle.toplink.essentials.threetier.ClientSession | acquireClientSession(oracle.toplink.essentials.sessions.Login login)PUBLIC:
Return a client session for this server session.
Each user/client connected to this server session must acquire there own client session
to communicate to the server through.
The client must provide its own login to use, and the client session returned
will have its own exclusive database connection. This connection will be used to perform
all database modification for all units of work acquired from the client session.
By default this does not use a lazy connection policy.
return acquireClientSession(new ConnectionPolicy(login));
| public oracle.toplink.essentials.threetier.ClientSession | acquireClientSession(oracle.toplink.essentials.threetier.ConnectionPolicy connectionPolicy)PUBLIC:
Return a client session for this server session.
The connection policy specifies how the client session's connection will be acquired.
if (!isConnected()) {
throw ValidationException.loginBeforeAllocatingClientSessions();
}
log(SessionLog.FINER, SessionLog.CONNECTION, "client_acquired");
if (!connectionPolicy.isPooled() && (connectionPolicy.getLogin() == null)) {
//the user has passed in a connection policy with no login info. Use the
//default info from the default connection policy
connectionPolicy.setPoolName(getDefaultConnectionPolicy().getPoolName());
connectionPolicy.setLogin(getDefaultConnectionPolicy().getLogin());
}
if (connectionPolicy.isPooled()) {
ConnectionPool pool = (ConnectionPool)getConnectionPools().get(connectionPolicy.getPoolName());
if (pool == null) {
throw ValidationException.poolNameDoesNotExist(connectionPolicy.getPoolName());
}
connectionPolicy.setLogin((Login)pool.getLogin().clone());
}
ClientSession client = null;
if (getProject().hasIsolatedClasses()) {
client = new IsolatedClientSession(this, connectionPolicy);
} else {
client = new ClientSession(this, connectionPolicy);
}
if (!connectionPolicy.isLazy()) {
acquireClientConnection(client);
}
return client;
| public oracle.toplink.essentials.sessions.UnitOfWork | acquireUnitOfWork()PUBLIC:
Return a unit of work for this session.
The unit of work is an object level transaction that allows
a group of changes to be applied as a unit.
First acquire a client session as server session does not allow direct units of work.
return acquireClientSession().acquireUnitOfWork();
| public void | addConnectionPool(java.lang.String poolName, oracle.toplink.essentials.sessions.Login login, int minNumberOfConnections, int maxNumberOfConnections)PUBLIC:
Add the connection pool.
Connections are pooled to share and restrict the number of database connections.
if (minNumberOfConnections > maxNumberOfConnections) {
throw ValidationException.maxSizeLessThanMinSize();
}
if (isConnected()) {
throw ValidationException.poolsMustBeConfiguredBeforeLogin();
}
ConnectionPool pool = null;
if (login.shouldUseExternalConnectionPooling()) {
pool = new ExternalConnectionPool(poolName, login, this);
} else {
pool = new ConnectionPool(poolName, login, minNumberOfConnections, maxNumberOfConnections, this);
}
addConnectionPool(pool);
| public void | addConnectionPool(oracle.toplink.essentials.threetier.ConnectionPool pool)PUBLIC:
Connection are pooled to share and restrict the number of database connections.
pool.setOwner(this);
getConnectionPools().put(pool.getName(), pool);
| public void | afterTransaction(boolean committed, boolean isExternalTransaction, oracle.toplink.essentials.internal.databaseaccess.Accessor accessor)INTERNAL:
Called after transaction is completed (committed or rolled back)
SequencingCallback callback = getSequencingHome().getSequencingCallback();
if (callback != null) {
callback.afterTransaction(accessor, committed);
}
| public oracle.toplink.essentials.internal.databaseaccess.Accessor | allocateReadConnection()INTERNAL:
Return a read connection from the read pool.
Note that depending on the type of pool this may be a shared or exclusive connection.
Each query execution is assigned a read connection.
Accessor connection = getReadConnectionPool().acquireConnection();
getEventManager().postAcquireConnection(connection);
return connection;
| public void | connect()INTERNAL:
Startup the server session, also startup all of the connection pools.
// make sure pools correspond to their logins
updateStandardConnectionPools();
// Configure the read pool
getReadConnectionPool().startUp();
setAccessor(allocateReadConnection());
releaseReadConnection(getAccessor());
for (Iterator poolsEnum = getConnectionPools().values().iterator(); poolsEnum.hasNext();) {
((ConnectionPool)poolsEnum.next()).startUp();
}
| public java.lang.Object | executeCall(oracle.toplink.essentials.queryframework.Call call, oracle.toplink.essentials.internal.sessions.AbstractRecord translationRow, oracle.toplink.essentials.queryframework.DatabaseQuery query)INTERNAL:
Override to acquire the connection from the pool at the last minute
RuntimeException exception = null;
Object object = null;
boolean accessorAllocated = false;
if (query.getAccessor() == null) {
query.setAccessor(this.allocateReadConnection());
accessorAllocated = true;
}
try {
object = query.getAccessor().executeCall(call, translationRow, this);
} catch (RuntimeException caughtException) {
exception = caughtException;
} finally {
if (call.isFinished()) {
//don't release the cursoredStream connection until Stream is closed
try {
if (accessorAllocated) {
releaseReadConnection(query.getAccessor());
query.setAccessor(null);
}
} catch (RuntimeException releaseException) {
if (exception == null) {
throw releaseException;
}
//else ignore
}
}
if (exception != null) {
throw exception;
}
}
return object;
| public oracle.toplink.essentials.threetier.ConnectionPool | getConnectionPool(java.lang.String poolName)PUBLIC:
Return the pool by name.
return (ConnectionPool)getConnectionPools().get(poolName);
| public java.util.Map | getConnectionPools()INTERNAL:
Connection are pooled to share and restrict the number of database connections.
return connectionPools;
| public oracle.toplink.essentials.threetier.ConnectionPolicy | getDefaultConnectionPolicy()PUBLIC:
The default connection policy is used by default by the acquireClientConnection() protocol.
By default it is a connection pool with min 5 and max 10 lazy pooled connections.
if (defaultConnectionPolicy == null) {
this.defaultConnectionPolicy = new ConnectionPolicy("default");
}
return defaultConnectionPolicy;
| public oracle.toplink.essentials.threetier.ConnectionPool | getDefaultConnectionPool()PUBLIC:
Return the default connection pool.
return getConnectionPool("default");
| public oracle.toplink.essentials.internal.sessions.AbstractSession | getExecutionSession(oracle.toplink.essentials.queryframework.DatabaseQuery query)INTERNAL:
Gets the session which this query will be executed on.
Generally will be called immediately before the call is translated,
which is immediately before session.executeCall.
Since the execution session also knows the correct datasource platform
to execute on, it is often used in the mappings where the platform is
needed for type conversion, or where calls are translated.
Is also the session with the accessor. Will return a ClientSession if
it is in transaction and has a write connection.
if (query.isObjectLevelModifyQuery()) {
throw QueryException.invalidQueryOnServerSession(query);
}
return this;
| public int | getMaxNumberOfNonPooledConnections()PUBLIC:
Return the number of non-pooled database connections allowed.
This can be enforced to make up for the resource limitation of most JDBC drivers and database clients.
By default this is 50.
return maxNumberOfNonPooledConnections;
| public int | getNumberOfNonPooledConnectionsUsed()INTERNAL:
Return the current number of non-pooled connections in use.
return numberOfNonPooledConnectionsUsed;
| public oracle.toplink.essentials.threetier.ConnectionPool | getReadConnectionPool()PUBLIC:
Return the read connection pool.
The read connection pool handles allocating connection for read queries.
By default a ReadConnnectionPool with a single connection. This is normally sufficient
as a JDBC connection can support concurrent reading. Multiple connections can also
be specified and may improve concurrency on some JDBC drivers/databases.
If external connection pooling is used, an external connection pool will be used by default.
If your JDBC driver does not support concurrency corrently a normal ConnectionPool can be used
to ensure exclusive access to the read connection, note that this will give less concurrency.
return readConnectionPool;
| protected oracle.toplink.essentials.sessions.Login | getReadLogin()INTERNAL:
Return the login for the read connection. Used by the platform autodetect feature
return getReadConnectionPool().getLogin();
| public oracle.toplink.essentials.internal.sequencing.SequencingServer | getSequencingServer()INTERNAL:
Return SequencingServer object owned by the session.
return getSequencingHome().getSequencingServer();
| public boolean | isConnected()PUBLIC:
Return if this session has been connected to the database.
if (getReadConnectionPool() == null) {
return false;
}
return getReadConnectionPool().isConnected();
| public boolean | isServerSession()INTERNAL:
Return if this session is a server session.
return true;
| public void | logout()PUBLIC:
Shutdown the server session, also shutdown all of the connection pools.
super.logout();
getReadConnectionPool().shutDown();
for (Iterator poolsEnum = getConnectionPools().values().iterator(); poolsEnum.hasNext();) {
((ConnectionPool)poolsEnum.next()).shutDown();
}
| public void | releaseClientSession(oracle.toplink.essentials.threetier.ClientSession clientSession)INTERNAL:
Release the clients connection resource.
if (clientSession.getConnectionPolicy().isPooled()) {
ConnectionPool pool = (ConnectionPool)getConnectionPools().get(clientSession.getConnectionPolicy().getPoolName());
getEventManager().preReleaseConnection(clientSession.getWriteConnection());
pool.releaseConnection(clientSession.getWriteConnection());
clientSession.setWriteConnection(null);
} else {
synchronized (this) {
clientSession.disconnect();
clientSession.setWriteConnection(null);
setNumberOfNonPooledConnectionsUsed(getNumberOfNonPooledConnectionsUsed() - 1);
notify();
}
}
| public void | releaseReadConnection(oracle.toplink.essentials.internal.databaseaccess.Accessor connection)INTERNAL:
Release the read connection back into the read pool.
getEventManager().preReleaseConnection(connection);
getReadConnectionPool().releaseConnection(connection);
| public void | setConnectionPools(java.util.Map connectionPools)INTERNAL:
Connection are pooled to share and restrict the number of database connections.
this.connectionPools = connectionPools;
| public void | setDefaultConnectionPolicy(oracle.toplink.essentials.threetier.ConnectionPolicy defaultConnectionPolicy)PUBLIC:
The default connection policy is used by default by the acquireClientConnection() protocol.
By default it is a connection pool with min 5 and max 10 lazy pooled connections.
this.defaultConnectionPolicy = defaultConnectionPolicy;
| public void | setDefaultConnectionPool()PUBLIC:
Creates and adds "default" connection pool using default parameter values
addConnectionPool("default", getDatasourceLogin(), 5, 10);
| public void | setMaxNumberOfNonPooledConnections(int maxNumberOfNonPooledConnections)PUBLIC:
Set the number of non-pooled database connections allowed.
This can be enforced to make up for the resource limitation of most JDBC drivers and database clients.
By default this is 50.
this.maxNumberOfNonPooledConnections = maxNumberOfNonPooledConnections;
| public void | setNumberOfNonPooledConnectionsUsed(int numberOfNonPooledConnectionsUsed)Set the current number of connections being used that are not from a connection pool.
this.numberOfNonPooledConnectionsUsed = numberOfNonPooledConnectionsUsed;
| public void | setReadConnectionPool(oracle.toplink.essentials.threetier.ConnectionPool readConnectionPool)PUBLIC:
Set the read connection pool.
The read connection pool handles allocating connection for read queries.
By default a ReadConnnectionPool with a single connection. This is normally sufficient
as a JDBC connection can support concurrent reading. Multiple connections can also
be specified and may improve concurrency on some JDBC drivers/databases.
If external connection pooling is used, an external connection pool will be used by default.
If your JDBC driver does not support concurrency corrently a normal ConnectionPool can be used
to ensure exclusive access to the read connection, note that this will give less concurrency.
if (isConnected()) {
throw ValidationException.cannotSetReadPoolSizeAfterLogin();
}
this.readConnectionPool = readConnectionPool;
this.readConnectionPool.setOwner(this);
| public void | setReadConnectionPool(oracle.toplink.essentials.sessions.Login readLogin)PUBLIC:
Creates and sets the new read connection pool.
if (isConnected()) {
throw ValidationException.poolsMustBeConfiguredBeforeLogin();
}
ConnectionPool pool = null;
if (readLogin.shouldUseExternalConnectionPooling()) {
pool = new ExternalConnectionPool("read", readLogin, this);
} else {
pool = new ConnectionPool("read", readLogin, 2, 2, this);
}
this.readConnectionPool = pool;
| protected void | updateStandardConnectionPools()INTERNAL:
Updates standard connection pools. Should not be called after session is connected.
This is needed in case of pools' logins been altered after the pool has been created
(SessionManager does that)
All pools should be re-created in case their type doesn't match their login.
In addition, sequenceConnectionPool should be removed in case its login
has shouldUseExternaltransactionController()==true (see setSequenceConnectionPool)
if (getDefaultConnectionPool() != null) {
if (getDefaultConnectionPool().isThereConflictBetweenLoginAndType()) {
setDefaultConnectionPool();
}
}
if (getReadConnectionPool() != null) {
if (getReadConnectionPool().isThereConflictBetweenLoginAndType()) {
setReadConnectionPool(getReadConnectionPool().getLogin());
}
}
| public void | useExclusiveReadConnectionPool(int minNumerOfConnections, int maxNumerOfConnections)PUBLIC:
Configure the read connection pool.
The read connection pool handles allocating connection for read queries.
By default a ReadConnnectionPool with a single connection. This is normally sufficient
as a JDBC connection can support concurrent reading. Multiple connections can also
be specified and may improve concurrency on some JDBC drivers/databases.
If external connection pooling is used, an external connection pool will be used by default.
If your JDBC driver does not support concurrency corrently a normal ConnectionPool can be used
to ensure exclusive access to the read connection, note that this will give less concurrency.
setReadConnectionPool(new ConnectionPool("read", getDatasourceLogin(), minNumerOfConnections, maxNumerOfConnections, this));
| public void | useExternalReadConnectionPool()PUBLIC:
Configure the read connection pool.
The read connection pool handles allocating connection for read queries.
By default a ReadConnnectionPool with a single connection. This is normally sufficient
as a JDBC connection can support concurrent reading. Multiple connections can also
be specified and may improve concurrency on some JDBC drivers/databases.
If external connection pooling is used, an external connection pool will be used by default.
If your JDBC driver does not support concurrency corrently a normal ConnectionPool can be used
to ensure exclusive access to the read connection, note that this will give less concurrency.
setReadConnectionPool(new ExternalConnectionPool("read", getDatasourceLogin(), this));
| public void | useReadConnectionPool(int minNumerOfConnections, int maxNumerOfConnections)PUBLIC:
Configure the read connection pool.
The read connection pool handles allocating connection for read queries.
By default a ReadConnnectionPool with a single connection. This is normally sufficient
as a JDBC connection can support concurrent reading. Multiple connections can also
be specified and may improve concurrency on some JDBC drivers/databases.
If external connection pooling is used, an external connection pool will be used by default.
If your JDBC driver does not support concurrency corrently a normal ConnectionPool can be used
to ensure exclusive access to the read connection, note that this will give less concurrency.
setReadConnectionPool(new ReadConnectionPool("read", getDatasourceLogin(), minNumerOfConnections, maxNumerOfConnections, this));
|
|