FileDocCategorySizeDatePackage
DatasourceAccessor.javaAPI DocGlassfish v2 API20913Tue May 22 16:54:20 BST 2007oracle.toplink.essentials.internal.databaseaccess

DatasourceAccessor

public abstract class DatasourceAccessor extends Object implements Accessor
INTERNAL: DatasourceAccessor is an abstract implementation of the Accessor interface providing common functionality to the concrete database and EIS accessors. It is responsible for connecting, transactions, call execution
see
Call
see
Login
author
James
since
OracleAS TopLink 10g (10.0.3)

Fields Summary
protected Object
datasourceConnection
Store the reference to the driver level connection.
protected Login
login
Store the login information that connected this accessor.
protected int
callCount
Keep track of the number of concurrent active calls. This is used for connection pooling for loadbalancing and for external connection pooling.
protected boolean
isInTransaction
Keep track if the accessor is within a transaction context
protected boolean
isConnected
Keep track of whether the accessor is "connected".
protected DatasourcePlatform
platform
This is also required to ensure all accessors for a session are using the same platform.
Constructors Summary
public DatasourceAccessor()
Default Constructor.

        this.isInTransaction = false;
        this.callCount = 0;
        this.isConnected = false;
    
Methods Summary
public voidafterJTSTransaction()
To be called after JTS transaction has been completed (committed or rolled back)

        if (usesExternalTransactionController()) {
            setIsInTransaction(false);
            if ((getDatasourceConnection() != null) && usesExternalConnectionPooling()) {
                closeConnection();
                setDatasourceConnection(null);
            }
        }
    
protected abstract voidbasicBeginTransaction(oracle.toplink.essentials.internal.sessions.AbstractSession session)
Begin the driver level transaction.

protected abstract voidbasicCommitTransaction(oracle.toplink.essentials.internal.sessions.AbstractSession session)
Commit the driver level transaction.

protected abstract java.lang.ObjectbasicExecuteCall(oracle.toplink.essentials.queryframework.Call call, oracle.toplink.essentials.internal.sessions.AbstractRecord row, oracle.toplink.essentials.internal.sessions.AbstractSession session)
Execute the call to driver level datasource.

protected abstract voidbasicRollbackTransaction(oracle.toplink.essentials.internal.sessions.AbstractSession session)
Rollback the driver level transaction.

public voidbeginTransaction(oracle.toplink.essentials.internal.sessions.AbstractSession session)
Begin a transaction on the database. If not using managed transaction begin a local transaction.

        if (usesExternalTransactionController()) {
            setIsInTransaction(true);
            return;
        }

        session.log(SessionLog.FINER, SessionLog.TRANSACTION, "begin_transaction", (Object[])null, this);

        try {
            session.startOperationProfile(SessionProfiler.TRANSACTION);
            incrementCallCount(session);
            basicBeginTransaction(session);
            setIsInTransaction(true);
        } finally {
            decrementCallCount();
            session.endOperationProfile(SessionProfiler.TRANSACTION);
        }
    
protected abstract voidbuildConnectLog(oracle.toplink.essentials.internal.sessions.AbstractSession session)
Build a log string of any driver metadata that can be obtained.

public java.lang.Objectclone()
Clone the accessor.

        try {
            DatasourceAccessor accessor = (DatasourceAccessor)super.clone();
            return accessor;
        } catch (CloneNotSupportedException exception) {
            throw new InternalError("clone not supported");
        }
    
public voidcloseConnection()
Close the accessor's connection. This is used only for external connection pooling when it is intended for the connection to be reconnected in the future.

        try {
            if (getDatasourceConnection() != null) {
                if (isDatasourceConnected()) {
                    closeDatasourceConnection();
                }
                setDatasourceConnection(null);
            }
        } catch (DatabaseException exception) {
            // Ignore
            setDatasourceConnection(null);
        }
    
protected abstract voidcloseDatasourceConnection()
Close the connection to the driver level datasource.

public voidcommitTransaction(oracle.toplink.essentials.internal.sessions.AbstractSession session)
Commit a transaction on the database. If using non-managed transaction commit the local transaction.

        if (usesExternalTransactionController()) {
            // if there is no external TX controller, then that means we are currently not synchronized
            // with a global JTS transaction.  In this case, there won't be any 'afterCompletion'
            // callbacks so we have to release the connection here.  It is possible (WLS 5.1) to choose
            // 'usesExternalTransactionController' on the login, but still acquire a uow that WON'T be
            // synchronized with a global TX.
            if (session.getExternalTransactionController() == null) {
                setIsInTransaction(false);
                if ((getDatasourceConnection() != null) && usesExternalConnectionPooling()) {
                    closeConnection();
                    setDatasourceConnection(null);
                }
            }
            return;
        }

        session.log(SessionLog.FINER, SessionLog.TRANSACTION, "commit_transaction", (Object[])null, this);

        try {
            session.startOperationProfile(SessionProfiler.TRANSACTION);
            incrementCallCount(session);
            basicCommitTransaction(session);

            // true=="committed"; false=="not jts transactioin"
            session.afterTransaction(true, false);
            setIsInTransaction(false);
        } finally {
            decrementCallCount();
            session.endOperationProfile(SessionProfiler.TRANSACTION);
        }
    
protected voidconnect(oracle.toplink.essentials.sessions.Login login)
Connect to the database. Exceptions are caught and re-thrown as TopLink exceptions.

        setDatasourceConnection(login.connectToDatasource(this));
        setIsConnected(true);
    
public voidconnect(oracle.toplink.essentials.sessions.Login login, oracle.toplink.essentials.internal.sessions.AbstractSession session)
Connect to the datasource. Through using a CCI ConnectionFactory. Catch exceptions and re-throw as TopLink exceptions.

        session.startOperationProfile(SessionProfiler.CONNECT);
        session.incrementProfile(SessionProfiler.TlConnects);

        try {
            if (session.shouldLog(SessionLog.CONFIG, SessionLog.CONNECTION)) {// Avoid printing if no logging required.
                session.log(SessionLog.CONFIG, SessionLog.CONNECTION, "connecting", new Object[] { login }, this);
            }
            setLogin(login);
            this.setDatasourcePlatform((DatasourcePlatform)session.getDatasourceLogin().getDatasourcePlatform());
            try {
                connect(login);
                setIsInTransaction(false);
            } catch (RuntimeException exception) {
                session.handleSevere(exception);
            }
            session.getEventManager().postConnect(this);
            incrementCallCount(session);
            try {
                buildConnectLog(session);
            } finally {
                decrementCallCount();
            }
        } finally {
            session.endOperationProfile(SessionProfiler.CONNECT);
        }
    
public synchronized voiddecrementCallCount()
Used for load balancing and external pooling.

        setCallCount(getCallCount() - 1);
        if (usesExternalConnectionPooling() && (!isInTransaction()) && (getCallCount() == 0)) {
            try {
                closeConnection();
            } catch (DatabaseException ignore) {
            }
            // Don't allow for errors to be masked by disconnect.
        }
    
public voiddisconnect(oracle.toplink.essentials.internal.sessions.AbstractSession session)
Disconnect from the datasource.

        session.log(SessionLog.CONFIG, SessionLog.CONNECTION, "disconnect", (Object[])null, this);

        if (getDatasourceConnection() == null) {
            return;
        }
        session.incrementProfile(SessionProfiler.TlDisconnects);
        session.startOperationProfile(SessionProfiler.CONNECT);
        closeDatasourceConnection();
        setDatasourceConnection(null);
        setIsInTransaction(false);
        session.endOperationProfile(SessionProfiler.CONNECT);
    
public java.lang.ObjectexecuteCall(oracle.toplink.essentials.queryframework.Call call, oracle.toplink.essentials.internal.sessions.AbstractRecord translationRow, oracle.toplink.essentials.internal.sessions.AbstractSession session)
Execute the call.

return
depending of the type either the row count, row or vector of rows.

        // If the login is null, then this accessor has never been connected.
        if (getLogin() == null) {
            throw DatabaseException.databaseAccessorNotConnected();
        }

        if (session.shouldLog(SessionLog.FINE, SessionLog.SQL)) {// pre-check to improve performance
            session.log(SessionLog.FINE, SessionLog.SQL, call.getLogString(this), (Object[])null, this, false);
        }

        Object result = basicExecuteCall(call, translationRow, session);

        return result;
    
public voidflushSelectCalls(oracle.toplink.essentials.internal.sessions.AbstractSession session)
Added as a result of Bug 2804663 - satisfy the Accessor interface implementation.

        // By default do nothing.
    
public intgetCallCount()
Used for load balancing and external pooling.

        return callCount;
    
public java.util.VectorgetColumnInfo(java.lang.String catalog, java.lang.String schema, java.lang.String tableName, java.lang.String columnName, oracle.toplink.essentials.internal.sessions.AbstractSession session)
Return column information for the specified database objects.

        return new Vector();
    
public java.sql.ConnectiongetConnection()
Helper method to return the JDBC connection for DatabaseAccessor. Was going to deprecate this, but since most clients are JDBC this is useful.

        return (java.sql.Connection)getDatasourceConnection();
    
public java.lang.ObjectgetDatasourceConnection()
Return the driver level connection.

        return datasourceConnection;
    
public oracle.toplink.essentials.internal.databaseaccess.DatasourcePlatformgetDatasourcePlatform()
Return the platform.

        return platform;
    
public oracle.toplink.essentials.sessions.LogingetLogin()
Return the login

        return login;
    
public java.util.VectorgetTableInfo(java.lang.String catalog, java.lang.String schema, java.lang.String tableName, java.lang.String[] types, oracle.toplink.essentials.internal.sessions.AbstractSession session)
Return table information for the specified database objects.

        return new Vector();
    
public synchronized voidincrementCallCount(oracle.toplink.essentials.internal.sessions.AbstractSession session)
Used for load balancing and external pooling.

        setCallCount(getCallCount() + 1);

        if (getCallCount() == 1) {
            // If the login is null, then this accessor has never been connected.
            if (getLogin() == null) {
                throw DatabaseException.databaseAccessorNotConnected();
            }

            // If the connection is no longer connected, it may have timed out.
            if (getDatasourceConnection() != null) {
                if (!isConnected()) {
                    if (isInTransaction()) {
                        throw DatabaseException.databaseAccessorNotConnected();
                    } else {
                        reconnect(session);
                    }
                }
            } else {
                // If ExternalConnectionPooling is used, the connection can be re-established.
                if (usesExternalConnectionPooling()) {
                    reconnect(session);
                } else {
                    throw DatabaseException.databaseAccessorNotConnected();
                }
            }
        }
    
public booleanisConnected()
Return true if the accessor is currently connected to a data source. Return false otherwise.

        if ((getDatasourceConnection() == null) && (getLogin() == null)) {
            return false;
        }
        if (usesExternalConnectionPooling()) {
            return true;// As can always reconnect.
        }

        if (getDatasourceConnection() == null) {
            return false;
        }

        return isDatasourceConnected();
    
protected abstract booleanisDatasourceConnected()
Return if the driver level connection is connected.

public booleanisInTransaction()
Return the transaction status of the receiver.

        return isInTransaction;
    
protected voidreconnect(oracle.toplink.essentials.internal.sessions.AbstractSession session)
Attempt to save some of the cost associated with getting a fresh connection. Assume the DatabaseDriver has been cached, if appropriate. Note: Connections that are participating in transactions will not be refreshd.^M

        session.log(SessionLog.FINEST, SessionLog.CONNECTION, "reconnecting_to_external_connection_pool");
        session.startOperationProfile(SessionProfiler.CONNECT);
        connect(getLogin());
        session.endOperationProfile(SessionProfiler.CONNECT);
    
public voidreestablishConnection(oracle.toplink.essentials.internal.sessions.AbstractSession session)
PUBLIC: Reconnect to the database. This can be used if the connection was disconnected or timedout. This ensures that the security is checked as it is public. Because the messages can take a long time to build, pre-check whether messages should be logged.

        if (session.shouldLog(SessionLog.CONFIG, SessionLog.CONNECTION)) {// Avoid printing if no logging required.		
            Object[] args = { getLogin() };
            session.log(SessionLog.CONFIG, SessionLog.CONNECTION, "reconnecting", args, this);
        }
        reconnect(session);
        setIsInTransaction(false);
        session.getEventManager().postConnect(this);
    
public voidrollbackTransaction(oracle.toplink.essentials.internal.sessions.AbstractSession session)
Rollback the transaction on the datasource. If not using managed transaction rollback the local transaction.

        if (usesExternalTransactionController()) {
            // if there is no external TX controller, then that means we are currently not synchronized
            // with a global JTS transaction.  In this case, there won't be any 'afterCompletion'
            // callbacks so we have to release the connection here.  It is possible (WLS 5.1) to choose
            // 'usesExternalTransactionController' on the login, but still acquire a uow that WON'T be
            // synchronized with a global TX.
            if (session.getExternalTransactionController() == null) {
                setIsInTransaction(false);
                if ((getDatasourceConnection() != null) && usesExternalConnectionPooling()) {
                    closeConnection();
                    setDatasourceConnection(null);
                }
            }
            return;
        }

        session.log(SessionLog.FINER, SessionLog.TRANSACTION, "rollback_transaction", (Object[])null, this);

        try {
            session.startOperationProfile(SessionProfiler.TRANSACTION);
            incrementCallCount(session);
            basicRollbackTransaction(session);
        } finally {
            // false=="rolled back"; false=="not jts transactioin"
            session.afterTransaction(false, false);
            setIsInTransaction(false);
            decrementCallCount();
            session.endOperationProfile(SessionProfiler.TRANSACTION);
        }
    
protected voidsetCallCount(int callCount)
Used for load balancing and external pooling.

        this.callCount = callCount;
    
protected voidsetDatasourceConnection(java.lang.Object connection)
If client requires to manually set connection they can use the connection manager.

        this.datasourceConnection = connection;
    
public voidsetDatasourcePlatform(oracle.toplink.essentials.internal.databaseaccess.DatasourcePlatform platform)
Set the platform. This should be set to the session's platform, not the connections which may not be configured correctly.

        this.platform = platform;
    
protected voidsetIsConnected(boolean isConnected)
Set whether the accessor has a connection to the "data store".

        this.isConnected = isConnected;
    
protected voidsetIsInTransaction(boolean value)
Set the transaction transaction status of the receiver.

        isInTransaction = value;
    
protected voidsetLogin(oracle.toplink.essentials.sessions.Login login)
SECURE: set the login

        this.login = login;
    
public booleanusesExternalConnectionPooling()
Return true if some external connection pool is in use.

        if (getLogin() == null) {
            throw DatabaseException.databaseAccessorNotConnected();
        }
        return getLogin().shouldUseExternalConnectionPooling();
    
public booleanusesExternalTransactionController()
Return true if some external transaction service is controlling transactions.

        if (getLogin() == null) {
            throw DatabaseException.databaseAccessorNotConnected();
        }
        return getLogin().shouldUseExternalTransactionController();
    
public voidwritesCompleted(oracle.toplink.essentials.internal.sessions.AbstractSession session)
This method will be called after a series of writes have been issued to mark where a particular set of writes has completed. It will be called from commitTransaction and may be called from writeChanges. Its main purpose is to ensure that the batched statements have been executed

        //this is a no-op in this method as we do not batch on this accessor