KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > oracle > toplink > essentials > threetier > ServerSession


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the "License"). You may not use this file except
5  * in compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * glassfish/bootstrap/legal/CDDLv1.0.txt or
9  * https://glassfish.dev.java.net/public/CDDLv1.0.html.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * HEADER in each file and include the License file at
15  * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
16  * add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your
18  * own identifying information: Portions Copyright [yyyy]
19  * [name of copyright owner]
20  */

21 // Copyright (c) 1998, 2006, Oracle. All rights reserved.
22
package oracle.toplink.essentials.threetier;
23
24 import java.util.*;
25 import oracle.toplink.essentials.internal.databaseaccess.*;
26 import oracle.toplink.essentials.queryframework.*;
27 import oracle.toplink.essentials.sessions.DatasourceLogin;
28 import oracle.toplink.essentials.sessions.Login;
29 import oracle.toplink.essentials.sessions.UnitOfWork;
30 import oracle.toplink.essentials.exceptions.*;
31 import oracle.toplink.essentials.internal.sequencing.SequencingCallback;
32 import oracle.toplink.essentials.internal.sequencing.SequencingServer;
33 import oracle.toplink.essentials.logging.SessionLog;
34 import oracle.toplink.essentials.internal.sessions.*;
35 import oracle.toplink.essentials.internal.sessions.AbstractRecord;
36 import oracle.toplink.essentials.internal.sessions.AbstractSession;
37
38 /**
39  * Implementation of Server
40  * INTERNAL:
41  * The public interface should be used.
42  * <p>
43  * <b>Purpose</b>: A single session that supports multiple user/clients connection at the same time.
44  * <p>
45  * <b>Description</b>: This session supports a shared session that can be used by multiple users
46  * or clients in a three-tiered application. It brokers client sessions to allow read and write access
47  * through a unified object cache. The server session provides a shared read only database connection that
48  * is used by all of its client for reads. All changes to objects and the database must be done through
49  * a unit of work acquired from the client session, this allows the changes to occur in a transactional object
50  * space and under a exclusive database connection.
51  * <p>
52  * <b>Responsibilities</b>:
53  * <ul>
54  * <li> Connecting/disconnecting the default reading login.
55  * <li> Reading objects and maintaining the object cache.
56  * <li> Brokering client sessions.
57  * <li> Disabling database modification through the shared connection.
58  * </ul>
59  * @see ClientSession
60  * @see UnitOfWork
61  */

62 public class ServerSession extends DatabaseSessionImpl implements Server {
63     protected ConnectionPool readConnectionPool;
64     protected Map connectionPools;
65     protected ConnectionPolicy defaultConnectionPolicy;
66     protected int maxNumberOfNonPooledConnections;
67     protected int numberOfNonPooledConnectionsUsed;
68     public static final int MAX_WRITE_CONNECTIONS = 10;
69     public static final int MIN_WRITE_CONNECTIONS = 5;
70     
71     /**
72      * INTERNAL:
73      * Create and return a new default server session.
74      * Used for EJB SessionManager to instantiate a server session
75      */

76     public ServerSession() {
77         super();
78         this.connectionPools = new HashMap(10);
79     }
80
81     /**
82      * PUBLIC:
83      * Create and return a new server session.
84      * By giving the login information on creation this allows the session to initialize itself
85      * to the platform given in the login. This constructor does not return a connected session.
86      * To connect the session to the database login() must be sent to it. The login(userName, password)
87      * method may also be used to connect the session, this allows for the user name and password
88      * to be given at login but for the other database information to be provided when the session is created.
89      * By default the server session uses a default connection pool with 5 min 10 max number of connections
90      * and a max number 50 non-pooled connections allowed.
91      */

92     public ServerSession(Login login) {
93         this(new oracle.toplink.essentials.sessions.Project(login));
94     }
95
96     /**
97      * PUBLIC:
98      * Create and return a new server session.
99      * Configure the min and max number of connections for the default pool.
100      */

101     public ServerSession(Login login, int minNumberOfPooledConnection, int maxNumberOfPooledConnection) {
102         this(new oracle.toplink.essentials.sessions.Project(login), minNumberOfPooledConnection, maxNumberOfPooledConnection);
103     }
104
105     /**
106      * PUBLIC:
107      * Create and return a new server session.
108      * Configure the default connection policy to be used.
109      * This policy is used on the "acquireClientSession()" protocol.
110      */

111     public ServerSession(Login login, ConnectionPolicy defaultConnectionPolicy) {
112         this(new oracle.toplink.essentials.sessions.Project(login), defaultConnectionPolicy);
113     }
114
115     /**
116      * PUBLIC:
117      * Create and return a new server session.
118      * By giving the project information on creation this allows the session to initialize itself
119      * to the platform given in the login. This constructor does not return a connected session.
120      * To connect the session to the database login() must be sent to it. The login(userName, password)
121      * method may also be used to connect the session, this allows for the user name and password
122      * to be given at login but for the other database information to be provided when the session is created.
123      * By default the server session uses a default connection pool with 5 min 10 max number of connections
124      * and a max number 50 non-pooled connections allowed.
125      */

126     public ServerSession(oracle.toplink.essentials.sessions.Project project) {
127         this(project, MIN_WRITE_CONNECTIONS, MAX_WRITE_CONNECTIONS);
128     }
129
130     /**
131      * PUBLIC:
132      * Create and return a new server session.
133      * Configure the min and max number of connections for the default pool.
134      */

135     public ServerSession(oracle.toplink.essentials.sessions.Project project, int minNumberOfPooledConnection, int maxNumberOfPooledConnection) {
136         this(project, new ConnectionPolicy("default"));
137
138         ConnectionPool pool = null;
139         if (project.getDatasourceLogin().shouldUseExternalConnectionPooling()) {
140             pool = new ExternalConnectionPool("default", project.getDatasourceLogin(), this);
141         } else {
142             pool = new ConnectionPool("default", project.getDatasourceLogin(), minNumberOfPooledConnection, maxNumberOfPooledConnection, this);
143         }
144         this.connectionPools.put("default", pool);
145     }
146
147     /**
148      * PUBLIC:
149      * Create and return a new server session.
150      * Configure the min and max number of connections for the default pool.
151      * Use the login from the project for the write pool. Use the passed
152      * in login for the read pool, if specified, or the project login if not.
153      *
154      * @param project the project associated with this session
155      * @param minNumberOfPooledConnection the minimum number of connections in the pool
156      * @param maxNumberOfPooledConnection the maximum number of connections in the pool
157      * @param readLogin the login used to create the read connection pool
158      */

159     public ServerSession(oracle.toplink.essentials.sessions.Project project, int minNumberOfPooledConnection, int maxNumberOfPooledConnection, oracle.toplink.essentials.sessions.Login readLogin) {
160         this(project, new ConnectionPolicy("default"), readLogin);
161
162         ConnectionPool pool = null;
163         if (project.getDatasourceLogin().shouldUseExternalConnectionPooling()) {
164             pool = new ExternalConnectionPool("default", project.getDatasourceLogin(), this);
165         } else {
166             pool = new ConnectionPool("default", project.getDatasourceLogin(), minNumberOfPooledConnection, maxNumberOfPooledConnection, this);
167         }
168         this.connectionPools.put("default", pool);
169     }
170
171     /**
172      * PUBLIC:
173      * Create and return a new server session.
174      * Configure the min and max number of connections for the default pool.
175      * Use the login from the project for the write pool. Use the passed
176      * in login for the read pool, if specified, or the project login if not.
177      * Use the sequenceLogin, if specified, for creating a connection pool
178      * to be used by sequencing through SequencingConnectionHandler
179      * sequenceLogin *MUST*:
180      * 1. specify *NON-JTS* connections (such as NON_JTS driver or read-only datasource);
181      * 2. sequenceLogin.shouldUseExternalTransactionController()==false
182      *
183      * @param project the project associated with this session
184      * @param minNumberOfPooledConnection the minimum number of connections in the pool
185      * @param maxNumberOfPooledConnection the maximum number of connections in the pool
186      * @param readLogin the login used to create the read connection pool
187      * @param sequenceLogin the login used to create a connection pool for sequencing
188      */

189     public ServerSession(oracle.toplink.essentials.sessions.Project project, int minNumberOfPooledConnection, int maxNumberOfPooledConnection, oracle.toplink.essentials.sessions.Login readLogin, oracle.toplink.essentials.sessions.Login sequenceLogin) {
190         this(project, new ConnectionPolicy("default"), readLogin, sequenceLogin);
191
192         ConnectionPool pool = null;
193         if (project.getDatasourceLogin().shouldUseExternalConnectionPooling()) {
194             pool = new ExternalConnectionPool("default", project.getDatasourceLogin(), this);
195         } else {
196             pool = new ConnectionPool("default", project.getDatasourceLogin(), minNumberOfPooledConnection, maxNumberOfPooledConnection, this);
197         }
198         this.connectionPools.put("default", pool);
199     }
200
201     /**
202      * PUBLIC:
203      * Create and return a new server session.
204      * Configure the default connection policy to be used.
205      * This policy is used on the "acquireClientSession()" protocol.
206      */

207     public ServerSession(oracle.toplink.essentials.sessions.Project project, ConnectionPolicy defaultConnectionPolicy) {
208         super(project);
209         this.connectionPools = new HashMap(10);
210         this.defaultConnectionPolicy = defaultConnectionPolicy;
211         this.maxNumberOfNonPooledConnections = 50;
212         this.numberOfNonPooledConnectionsUsed = 0;
213         setReadConnectionPool(project.getDatasourceLogin());
214     }
215
216     /**
217      * PUBLIC:
218      * Create and return a new server session.
219      * Configure the default connection policy to be used.
220      * This policy is used on the "acquireClientSession()" protocol.
221      * Use the readLogin, if specified, for logging into the read
222      * connection pool.
223      */

224     public ServerSession(oracle.toplink.essentials.sessions.Project project, ConnectionPolicy defaultConnectionPolicy, oracle.toplink.essentials.sessions.Login readLogin) {
225         super(project);
226         this.connectionPools = new HashMap(10);
227         this.defaultConnectionPolicy = defaultConnectionPolicy;
228         this.maxNumberOfNonPooledConnections = 50;
229         this.numberOfNonPooledConnectionsUsed = 0;
230         Login login = (readLogin != null) ? readLogin : project.getDatasourceLogin();
231         setReadConnectionPool(login);
232     }
233
234     /**
235      * PUBLIC:
236      * Create and return a new server session.
237      * Configure the default connection policy to be used.
238      * This policy is used on the "acquireClientSession()" protocol.
239      * Use the readLogin, if specified, for logging into the read
240      * connection pool.
241      * Use the sequenceLogin, if specified, for creating a connection pool
242      * to be used by sequencing through SequencingConnectionHandler
243      * sequenceLogin *MUST*:
244      * 1. specify *NON-JTS* connections (such as NON_JTS driver or read-only datasource);
245      * 2. sequenceLogin.shouldUseExternalTransactionController()==false
246      *
247      */

248     public ServerSession(oracle.toplink.essentials.sessions.Project project, ConnectionPolicy defaultConnectionPolicy, oracle.toplink.essentials.sessions.Login readLogin, oracle.toplink.essentials.sessions.Login sequenceLogin) {
249         this(project, defaultConnectionPolicy, readLogin);
250
251         if (sequenceLogin != null) {
252             //** sequencing refactoring
253
getSequencingControl().setShouldUseSeparateConnection(true);
254             getSequencingControl().setLogin(sequenceLogin);
255         }
256     }
257
258     /**
259      * INTERNAL:
260      * Allocate the client's connection resource.
261      */

262     public void acquireClientConnection(ClientSession clientSession) throws DatabaseException, ConcurrencyException {
263         if (clientSession.getConnectionPolicy().isPooled()) {
264             ConnectionPool pool = (ConnectionPool)getConnectionPools().get(clientSession.getConnectionPolicy().getPoolName());
265             Accessor connection = pool.acquireConnection();
266             clientSession.setWriteConnection(connection);
267             getEventManager().postAcquireConnection(connection);
268         } else {
269             // This method is synchronized, so while is not required, only if.
270
synchronized (this) {
271                 while (getNumberOfNonPooledConnectionsUsed() >= getMaxNumberOfNonPooledConnections()) {
272                     try {
273                         wait();// Notify is called when connections are released.
274
} catch (InterruptedException JavaDoc exception) {
275                         throw ConcurrencyException.waitFailureOnServerSession(exception);
276                     }
277                 }
278
279                 setNumberOfNonPooledConnectionsUsed(getNumberOfNonPooledConnectionsUsed() + 1);
280                 clientSession.setWriteConnection(clientSession.getLogin().buildAccessor());
281                 clientSession.connect();
282             }
283         }
284     }
285
286     /**
287      * PUBLIC:
288      * Return a client session for this server session.
289      * Each user/client connected to this server session must acquire there own client session
290      * to communicate to the server through.
291      * This method allows for a client session to be acquired sharing the same login as the server session.
292      */

293     public ClientSession acquireClientSession() throws DatabaseException {
294         return acquireClientSession((ConnectionPolicy)getDefaultConnectionPolicy().clone());
295     }
296
297     /**
298      * PUBLIC:
299      * Return a client session for this server session.
300      * Each user/client connected to this server session must acquire there own client session
301      * to communicate to the server through.
302      * This method allows for a client session to be acquired sharing its connection from a pool
303      * of connection allocated on the server session.
304      * By default this uses a lazy connection policy.
305      */

306     public ClientSession acquireClientSession(String JavaDoc poolName) throws DatabaseException {
307         return acquireClientSession(new ConnectionPolicy(poolName));
308     }
309
310     /**
311      * PUBLIC:
312      * Return a client session for this server session.
313      * Each user/client connected to this server session must acquire there own client session
314      * to communicate to the server through.
315      * The client must provide its own login to use, and the client session returned
316      * will have its own exclusive database connection. This connection will be used to perform
317      * all database modification for all units of work acquired from the client session.
318      * By default this does not use a lazy connection policy.
319      */

320     public ClientSession acquireClientSession(Login login) throws DatabaseException {
321         return acquireClientSession(new ConnectionPolicy(login));
322     }
323
324     /**
325      * PUBLIC:
326      * Return a client session for this server session.
327      * The connection policy specifies how the client session's connection will be acquired.
328      */

329     public ClientSession acquireClientSession(ConnectionPolicy connectionPolicy) throws DatabaseException, ValidationException {
330         if (!isConnected()) {
331             throw ValidationException.loginBeforeAllocatingClientSessions();
332         }
333
334         log(SessionLog.FINER, SessionLog.CONNECTION, "client_acquired");
335         if (!connectionPolicy.isPooled() && (connectionPolicy.getLogin() == null)) {
336             //the user has passed in a connection policy with no login info. Use the
337
//default info from the default connection policy
338
connectionPolicy.setPoolName(getDefaultConnectionPolicy().getPoolName());
339             connectionPolicy.setLogin(getDefaultConnectionPolicy().getLogin());
340         }
341         if (connectionPolicy.isPooled()) {
342             ConnectionPool pool = (ConnectionPool)getConnectionPools().get(connectionPolicy.getPoolName());
343             if (pool == null) {
344                 throw ValidationException.poolNameDoesNotExist(connectionPolicy.getPoolName());
345             }
346             connectionPolicy.setLogin((Login)pool.getLogin().clone());
347         }
348         ClientSession client = null;
349         if (getProject().hasIsolatedClasses()) {
350             client = new IsolatedClientSession(this, connectionPolicy);
351         } else {
352             client = new ClientSession(this, connectionPolicy);
353         }
354         if (!connectionPolicy.isLazy()) {
355             acquireClientConnection(client);
356         }
357
358         return client;
359     }
360
361     /**
362      * PUBLIC:
363      * Return a unit of work for this session.
364      * The unit of work is an object level transaction that allows
365      * a group of changes to be applied as a unit.
366      * First acquire a client session as server session does not allow direct units of work.
367      *
368      * @see UnitOfWork
369      */

370     public UnitOfWork acquireUnitOfWork() {
371         return acquireClientSession().acquireUnitOfWork();
372     }
373
374     /**
375      * PUBLIC:
376      * Add the connection pool.
377      * Connections are pooled to share and restrict the number of database connections.
378      */

379     public void addConnectionPool(String JavaDoc poolName, Login login, int minNumberOfConnections, int maxNumberOfConnections) throws ValidationException {
380         if (minNumberOfConnections > maxNumberOfConnections) {
381             throw ValidationException.maxSizeLessThanMinSize();
382         }
383         if (isConnected()) {
384             throw ValidationException.poolsMustBeConfiguredBeforeLogin();
385         }
386         ConnectionPool pool = null;
387         if (login.shouldUseExternalConnectionPooling()) {
388             pool = new ExternalConnectionPool(poolName, login, this);
389         } else {
390             pool = new ConnectionPool(poolName, login, minNumberOfConnections, maxNumberOfConnections, this);
391         }
392         addConnectionPool(pool);
393     }
394
395     /**
396      * PUBLIC:
397      * Connection are pooled to share and restrict the number of database connections.
398      */

399     public void addConnectionPool(ConnectionPool pool) {
400         pool.setOwner(this);
401         getConnectionPools().put(pool.getName(), pool);
402
403     }
404
405     /**
406      * INTERNAL:
407      * Called after transaction is completed (committed or rolled back)
408      */

409     public void afterTransaction(boolean committed, boolean isExternalTransaction, Accessor accessor) {
410         SequencingCallback callback = getSequencingHome().getSequencingCallback();
411         if (callback != null) {
412             callback.afterTransaction(accessor, committed);
413         }
414     }
415
416     /**
417      * INTERNAL:
418      * Return a read connection from the read pool.
419      * Note that depending on the type of pool this may be a shared or exclusive connection.
420      * Each query execution is assigned a read connection.
421      */

422     public Accessor allocateReadConnection() {
423         Accessor connection = getReadConnectionPool().acquireConnection();
424         getEventManager().postAcquireConnection(connection);
425         return connection;
426     }
427
428     /**
429      * INTERNAL:
430      * Startup the server session, also startup all of the connection pools.
431      */

432     public void connect(boolean updatePlatform) {
433         // make sure pools correspond to their logins
434
updateStandardConnectionPools();
435         if (updatePlatform){
436             //we autodetected the platform
437
for (Iterator pools = getConnectionPools().values().iterator(); pools.hasNext();){
438                 ((DatasourceLogin)((ConnectionPool)pools.next()).getLogin()).usePlatform(getDatasourceLogin().getDatasourcePlatform());
439             }
440             ((DatasourceLogin)getReadConnectionPool().getLogin()).usePlatform(getDatasourceLogin().getDatasourcePlatform());
441         }
442         // Configure the read pool
443
getReadConnectionPool().startUp();
444         setAccessor(allocateReadConnection());
445         releaseReadConnection(getAccessor());
446
447         for (Iterator poolsEnum = getConnectionPools().values().iterator(); poolsEnum.hasNext();) {
448             ((ConnectionPool)poolsEnum.next()).startUp();
449         }
450     }
451
452     /**
453      * INTERNAL:
454      * Override to acquire the connection from the pool at the last minute
455      */

456     public Object JavaDoc executeCall(Call call, AbstractRecord translationRow, DatabaseQuery query) throws DatabaseException {
457         RuntimeException JavaDoc exception = null;
458         Object JavaDoc object = null;
459         boolean accessorAllocated = false;
460         if (query.getAccessor() == null) {
461             query.setAccessor(this.allocateReadConnection());
462             accessorAllocated = true;
463         }
464         try {
465             object = query.getAccessor().executeCall(call, translationRow, this);
466         } catch (RuntimeException JavaDoc caughtException) {
467             exception = caughtException;
468         } finally {
469             if (call.isFinished()) {
470                 //don't release the cursoredStream connection until Stream is closed
471
try {
472                     if (accessorAllocated) {
473                         releaseReadConnection(query.getAccessor());
474                         query.setAccessor(null);
475                     }
476                 } catch (RuntimeException JavaDoc releaseException) {
477                     if (exception == null) {
478                         throw releaseException;
479                     }
480                     //else ignore
481
}
482             }
483             if (exception != null) {
484                 throw exception;
485             }
486         }
487         return object;
488     }
489
490     /**
491      * PUBLIC:
492      * Return the pool by name.
493      */

494     public ConnectionPool getConnectionPool(String JavaDoc poolName) {
495         return (ConnectionPool)getConnectionPools().get(poolName);
496     }
497
498     /**
499      * INTERNAL:
500      * Connection are pooled to share and restrict the number of database connections.
501      */

502     public Map getConnectionPools() {
503         return connectionPools;
504     }
505
506     /**
507      * PUBLIC:
508      * The default connection policy is used by default by the acquireClientConnection() protocol.
509      * By default it is a connection pool with min 5 and max 10 lazy pooled connections.
510      */

511     public ConnectionPolicy getDefaultConnectionPolicy() {
512         if (defaultConnectionPolicy == null) {
513             this.defaultConnectionPolicy = new ConnectionPolicy("default");
514         }
515         return defaultConnectionPolicy;
516     }
517
518     /**
519      * PUBLIC:
520      * Return the default connection pool.
521      */

522     public ConnectionPool getDefaultConnectionPool() {
523         return getConnectionPool("default");
524     }
525
526     /**
527      * INTERNAL:
528      * Gets the session which this query will be executed on.
529      * Generally will be called immediately before the call is translated,
530      * which is immediately before session.executeCall.
531      * <p>
532      * Since the execution session also knows the correct datasource platform
533      * to execute on, it is often used in the mappings where the platform is
534      * needed for type conversion, or where calls are translated.
535      * <p>
536      * Is also the session with the accessor. Will return a ClientSession if
537      * it is in transaction and has a write connection.
538      * @return a session with a live accessor
539      * @param query may store session name or reference class for brokers case
540      */

541     public AbstractSession getExecutionSession(DatabaseQuery query) {
542         if (query.isObjectLevelModifyQuery()) {
543             throw QueryException.invalidQueryOnServerSession(query);
544         }
545         return this;
546     }
547
548     /**
549      * PUBLIC:
550      * Return the number of non-pooled database connections allowed.
551      * This can be enforced to make up for the resource limitation of most JDBC drivers and database clients.
552      * By default this is 50.
553      */

554     public int getMaxNumberOfNonPooledConnections() {
555         return maxNumberOfNonPooledConnections;
556     }
557
558     /**
559      * INTERNAL:
560      * Return the current number of non-pooled connections in use.
561      */

562     public int getNumberOfNonPooledConnectionsUsed() {
563         return numberOfNonPooledConnectionsUsed;
564     }
565
566     /**
567      * INTERNAL:
568      * Return the login for the read connection. Used by the platform autodetect feature
569      */

570     protected Login getReadLogin(){
571         return getReadConnectionPool().getLogin();
572     }
573
574     /**
575      * PUBLIC:
576      * Return the read connection pool.
577      * The read connection pool handles allocating connection for read queries.
578      * By default a ReadConnnectionPool with a single connection. This is normally sufficient
579      * as a JDBC connection can support concurrent reading. Multiple connections can also
580      * be specified and may improve concurrency on some JDBC drivers/databases.
581      * If external connection pooling is used, an external connection pool will be used by default.
582      * If your JDBC driver does not support concurrency corrently a normal ConnectionPool can be used
583      * to ensure exclusive access to the read connection, note that this will give less concurrency.
584      */

585     public ConnectionPool getReadConnectionPool() {
586         return readConnectionPool;
587     }
588
589     /**
590      * PUBLIC:
591      * Return if this session has been connected to the database.
592      */

593     public boolean isConnected() {
594         if (getReadConnectionPool() == null) {
595             return false;
596         }
597
598         return getReadConnectionPool().isConnected();
599     }
600
601     /**
602      * INTERNAL:
603      * Return if this session is a server session.
604      */

605     public boolean isServerSession() {
606         return true;
607     }
608
609     /**
610      * PUBLIC:
611      * Shutdown the server session, also shutdown all of the connection pools.
612      */

613     public void logout() {
614         super.logout();
615
616         getReadConnectionPool().shutDown();
617
618         for (Iterator poolsEnum = getConnectionPools().values().iterator(); poolsEnum.hasNext();) {
619             ((ConnectionPool)poolsEnum.next()).shutDown();
620         }
621     }
622
623     /**
624      * INTERNAL:
625      * Release the clients connection resource.
626      */

627     public void releaseClientSession(ClientSession clientSession) throws DatabaseException {
628         if (clientSession.getConnectionPolicy().isPooled()) {
629             ConnectionPool pool = (ConnectionPool)getConnectionPools().get(clientSession.getConnectionPolicy().getPoolName());
630             getEventManager().preReleaseConnection(clientSession.getWriteConnection());
631             pool.releaseConnection(clientSession.getWriteConnection());
632             clientSession.setWriteConnection(null);
633         } else {
634             synchronized (this) {
635                 clientSession.disconnect();
636                 clientSession.setWriteConnection(null);
637                 setNumberOfNonPooledConnectionsUsed(getNumberOfNonPooledConnectionsUsed() - 1);
638                 notify();
639             }
640         }
641     }
642
643     /**
644      * INTERNAL:
645      * Release the read connection back into the read pool.
646      */

647     public void releaseReadConnection(Accessor connection) {
648         getEventManager().preReleaseConnection(connection);
649         getReadConnectionPool().releaseConnection(connection);
650     }
651
652     /**
653      * INTERNAL:
654      * Connection are pooled to share and restrict the number of database connections.
655      */

656     public void setConnectionPools(Map connectionPools) {
657         this.connectionPools = connectionPools;
658     }
659
660     /**
661      * PUBLIC:
662      * The default connection policy is used by default by the acquireClientConnection() protocol.
663      * By default it is a connection pool with min 5 and max 10 lazy pooled connections.
664      */

665     public void setDefaultConnectionPolicy(ConnectionPolicy defaultConnectionPolicy) {
666         this.defaultConnectionPolicy = defaultConnectionPolicy;
667     }
668
669     /**
670      * PUBLIC:
671      * Creates and adds "default" connection pool using default parameter values
672      */

673     public void setDefaultConnectionPool() {
674         addConnectionPool("default", getDatasourceLogin(), 5, 10);
675     }
676
677     /**
678      * PUBLIC:
679      * Set the number of non-pooled database connections allowed.
680      * This can be enforced to make up for the resource limitation of most JDBC drivers and database clients.
681      * By default this is 50.
682      */

683     public void setMaxNumberOfNonPooledConnections(int maxNumberOfNonPooledConnections) {
684         this.maxNumberOfNonPooledConnections = maxNumberOfNonPooledConnections;
685     }
686
687     /**
688      * Set the current number of connections being used that are not from a connection pool.
689      * @param int
690      */

691     public void setNumberOfNonPooledConnectionsUsed(int numberOfNonPooledConnectionsUsed) {
692         this.numberOfNonPooledConnectionsUsed = numberOfNonPooledConnectionsUsed;
693     }
694
695     /**
696      * PUBLIC:
697      * Set the read connection pool.
698      * The read connection pool handles allocating connection for read queries.
699      * By default a ReadConnnectionPool with a single connection. This is normally sufficient
700      * as a JDBC connection can support concurrent reading. Multiple connections can also
701      * be specified and may improve concurrency on some JDBC drivers/databases.
702      * If external connection pooling is used, an external connection pool will be used by default.
703      * If your JDBC driver does not support concurrency corrently a normal ConnectionPool can be used
704      * to ensure exclusive access to the read connection, note that this will give less concurrency.
705      */

706     public void setReadConnectionPool(ConnectionPool readConnectionPool) {
707         if (isConnected()) {
708             throw ValidationException.cannotSetReadPoolSizeAfterLogin();
709         }
710         this.readConnectionPool = readConnectionPool;
711         this.readConnectionPool.setOwner(this);
712     }
713
714     /**
715      * PUBLIC:
716      * Creates and sets the new read connection pool.
717      */

718     public void setReadConnectionPool(Login readLogin) throws ValidationException {
719         if (isConnected()) {
720             throw ValidationException.poolsMustBeConfiguredBeforeLogin();
721         }
722         ConnectionPool pool = null;
723         if (readLogin.shouldUseExternalConnectionPooling()) {
724             pool = new ExternalConnectionPool("read", readLogin, this);
725         } else {
726             pool = new ConnectionPool("read", readLogin, 2, 2, this);
727         }
728         this.readConnectionPool = pool;
729     }
730
731     /**
732      * INTERNAL:
733      * Updates standard connection pools. Should not be called after session is connected.
734      * This is needed in case of pools' logins been altered after the pool has been created
735      * (SessionManager does that)
736      * All pools should be re-created in case their type doesn't match their login.
737      * In addition, sequenceConnectionPool should be removed in case its login
738      * has shouldUseExternaltransactionController()==true (see setSequenceConnectionPool)
739      */

740     protected void updateStandardConnectionPools() {
741         if (getDefaultConnectionPool() != null) {
742             if (getDefaultConnectionPool().isThereConflictBetweenLoginAndType()) {
743                 setDefaultConnectionPool();
744             }
745         }
746
747         if (getReadConnectionPool() != null) {
748             if (getReadConnectionPool().isThereConflictBetweenLoginAndType()) {
749                 setReadConnectionPool(getReadConnectionPool().getLogin());
750             }
751         }
752     }
753
754     /**
755      * PUBLIC:
756      * Configure the read connection pool.
757      * The read connection pool handles allocating connection for read queries.
758      * By default a ReadConnnectionPool with a single connection. This is normally sufficient
759      * as a JDBC connection can support concurrent reading. Multiple connections can also
760      * be specified and may improve concurrency on some JDBC drivers/databases.
761      * If external connection pooling is used, an external connection pool will be used by default.
762      * If your JDBC driver does not support concurrency corrently a normal ConnectionPool can be used
763      * to ensure exclusive access to the read connection, note that this will give less concurrency.
764      */

765     public void useExclusiveReadConnectionPool(int minNumerOfConnections, int maxNumerOfConnections) {
766         setReadConnectionPool(new ConnectionPool("read", getDatasourceLogin(), minNumerOfConnections, maxNumerOfConnections, this));
767     }
768
769     /**
770      * PUBLIC:
771      * Configure the read connection pool.
772      * The read connection pool handles allocating connection for read queries.
773      * By default a ReadConnnectionPool with a single connection. This is normally sufficient
774      * as a JDBC connection can support concurrent reading. Multiple connections can also
775      * be specified and may improve concurrency on some JDBC drivers/databases.
776      * If external connection pooling is used, an external connection pool will be used by default.
777      * If your JDBC driver does not support concurrency corrently a normal ConnectionPool can be used
778      * to ensure exclusive access to the read connection, note that this will give less concurrency.
779      */

780     public void useExternalReadConnectionPool() {
781         setReadConnectionPool(new ExternalConnectionPool("read", getDatasourceLogin(), this));
782     }
783
784     /**
785      * PUBLIC:
786      * Configure the read connection pool.
787      * The read connection pool handles allocating connection for read queries.
788      * By default a ReadConnnectionPool with a single connection. This is normally sufficient
789      * as a JDBC connection can support concurrent reading. Multiple connections can also
790      * be specified and may improve concurrency on some JDBC drivers/databases.
791      * If external connection pooling is used, an external connection pool will be used by default.
792      * If your JDBC driver does not support concurrency corrently a normal ConnectionPool can be used
793      * to ensure exclusive access to the read connection, note that this will give less concurrency.
794      */

795     public void useReadConnectionPool(int minNumerOfConnections, int maxNumerOfConnections) {
796         setReadConnectionPool(new ReadConnectionPool("read", getDatasourceLogin(), minNumerOfConnections, maxNumerOfConnections, this));
797     }
798
799     /**
800      * INTERNAL:
801      * Return SequencingServer object owned by the session.
802      */

803     public SequencingServer getSequencingServer() {
804         return getSequencingHome().getSequencingServer();
805     }
806 }
807
Popular Tags