org.enhydra.jdbc.standard
Class StandardXAConnection

java.lang.Object
  extended by org.enhydra.jdbc.standard.StandardPooledConnection
      extended by org.enhydra.jdbc.standard.StandardXAConnection
All Implemented Interfaces:
java.lang.Runnable, javax.naming.Referenceable, javax.sql.PooledConnection, javax.sql.XAConnection, javax.transaction.xa.XAResource
Direct Known Subclasses:
IdbXAConnection, InformixXAConnection, OracleXAConnection, SybaseXAConnection

public class StandardXAConnection
extends StandardPooledConnection
implements javax.sql.XAConnection, javax.transaction.xa.XAResource, javax.naming.Referenceable, java.lang.Runnable

Provides a generic wrapper for JDBC 1 drivers. JDBC 1 drivers always associate a single transaction at every point in time with a physical connection. J2EE drivers, on the other hand, allow an XAResource (and therefore an XAConnection with which it has a one to one mapping) to switch between global transactions.

To accomodate this, the StandardXADataSource class maintains a list of Connection objects. When the Transaction Manager associates an XID with a StandardXAConnection, it looks for a physical connection which is associated with that transaction.

The "current" connection (super.con and curCon) is the connection currently being used by the application (i.e. getConnection has been called, but not Connection.close()). The current connection is removed and handed to the data source if it becomes associated with a global transaction.


Field Summary
 StandardXAConnectionHandle connectionHandle
           
protected  StandardXAStatefulConnection curCon
           
 boolean thisAutoCommit
           
 java.lang.Thread timerThread
           
 javax.transaction.TransactionManager transactionManager
           
protected  StandardXADataSource xaDataSource
           
 
Fields inherited from class org.enhydra.jdbc.standard.StandardPooledConnection
con, dataSource, log
 
Fields inherited from interface javax.transaction.xa.XAResource
TMENDRSCAN, TMFAIL, TMJOIN, TMNOFLAGS, TMONEPHASE, TMRESUME, TMSTARTRSCAN, TMSUCCESS, TMSUSPEND, XA_OK, XA_RDONLY
 
Constructor Summary
StandardXAConnection(StandardXADataSource dataSource, java.lang.String user, java.lang.String password)
          Creates the first free connection.
 
Method Summary
 StandardXAStatefulConnection checkPreparedState(javax.transaction.xa.Xid xid)
          Does most of the work of a generic prepare.
 void close()
          Close this XA connection.
 void commit(javax.transaction.xa.Xid xid, boolean onePhase)
          Performs a commit on this resource manager's branch of the global transaction.
 void doStart(javax.transaction.xa.Xid xid, int flags)
          Does most of the work of the start() call (below).
 void end(javax.transaction.xa.Xid xid, int flags)
          Ends a connection's association with a global transaction.
 void forget(javax.transaction.xa.Xid xid)
          This is called by a TM when the RM has reported a heuristic completion.
 boolean getCommitOnPrepare()
           
 java.sql.Connection getConnection()
          Creates a new StandardXAConnectionHandle for use by an application.
 javax.naming.Reference getReference()
           
 int getTransactionTimeout()
           
 javax.transaction.xa.XAResource getXAResource()
          We are required to maintain a 1-1 mapping between an XAConnection and its corresponding XAResource.
 boolean isSameRM(javax.transaction.xa.XAResource xares)
           
protected  void newConnectionHandle()
           
 int prepare(javax.transaction.xa.Xid xid)
          Prepares to perform a commit.
 javax.transaction.xa.Xid[] recover(int flag)
          Called by the transaction manager during recovery.
 void rollback(javax.transaction.xa.Xid xid)
          PERFORMS a rollback on this resource manager's branch of the global transaction.
 void run()
          Periodically checks for timed out connections.
 void setCommitOnPrepare(boolean commitOnPrepare)
           
 void setTransactionManager(javax.transaction.TransactionManager tm)
           
 boolean setTransactionTimeout(int seconds)
          Accessor methods for timeout.
 void start(javax.transaction.xa.Xid xid, int flags)
          Associates this XAConnection with a global transaction.
 java.lang.String toString()
           
 
Methods inherited from class org.enhydra.jdbc.standard.StandardPooledConnection
addConnectionEventListener, connectionErrorOccurred, getPhysicalConnection, removeConnectionEventListener, setLogger
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 
Methods inherited from interface javax.sql.PooledConnection
addConnectionEventListener, addStatementEventListener, removeConnectionEventListener, removeStatementEventListener
 

Field Detail

curCon

protected StandardXAStatefulConnection curCon

timerThread

public java.lang.Thread timerThread

transactionManager

public javax.transaction.TransactionManager transactionManager

connectionHandle

public StandardXAConnectionHandle connectionHandle

xaDataSource

protected StandardXADataSource xaDataSource

thisAutoCommit

public boolean thisAutoCommit
Constructor Detail

StandardXAConnection

public StandardXAConnection(StandardXADataSource dataSource,
                            java.lang.String user,
                            java.lang.String password)
                     throws java.sql.SQLException
Creates the first free connection.

Throws:
java.sql.SQLException
Method Detail

getXAResource

public javax.transaction.xa.XAResource getXAResource()
We are required to maintain a 1-1 mapping between an XAConnection and its corresponding XAResource. We achieve this by implementing both interfaces in the same class.

Specified by:
getXAResource in interface javax.sql.XAConnection

getConnection

public java.sql.Connection getConnection()
                                  throws java.sql.SQLException
Creates a new StandardXAConnectionHandle for use by an application. If there is already an StandardXAConnectionHandle in use then it is closed (i.e. the application has the connection withdrawn).

This method always returns a Connection in the free state (i.e. (not associated with an Xid). This is necessary since, unless Start (Xid, flags) gets called, the Connection must do local transaction processing.

Specified by:
getConnection in interface javax.sql.PooledConnection
Overrides:
getConnection in class StandardPooledConnection
Throws:
java.sql.SQLException

newConnectionHandle

protected void newConnectionHandle()
Overrides:
newConnectionHandle in class StandardPooledConnection

setTransactionManager

public void setTransactionManager(javax.transaction.TransactionManager tm)

close

public void close()
           throws java.sql.SQLException
Close this XA connection.

Specified by:
close in interface javax.sql.PooledConnection
Overrides:
close in class StandardPooledConnection
Throws:
java.sql.SQLException

doStart

public void doStart(javax.transaction.xa.Xid xid,
                    int flags)
             throws javax.transaction.xa.XAException
Does most of the work of the start() call (below). Kept as a separate method so that subclasses can call it and retain the curCon property.

Throws:
javax.transaction.xa.XAException

start

public void start(javax.transaction.xa.Xid xid,
                  int flags)
           throws javax.transaction.xa.XAException
Associates this XAConnection with a global transaction. This is the only method which can associate the current connection with a global transaction. It acts only on the current connection which must have been previously established using getConnection.

Specified by:
start in interface javax.transaction.xa.XAResource
Throws:
javax.transaction.xa.XAException

end

public void end(javax.transaction.xa.Xid xid,
                int flags)
         throws javax.transaction.xa.XAException
Ends a connection's association with a global transaction.

It need not act on the current transaction. There is an interval between being returned to the pool manager and being invoked by the transaction manager during which the current connection can change.

Note that the only effect is to change the connection state.

Specified by:
end in interface javax.transaction.xa.XAResource
Throws:
javax.transaction.xa.XAException

checkPreparedState

public StandardXAStatefulConnection checkPreparedState(javax.transaction.xa.Xid xid)
                                                throws javax.transaction.xa.XAException
Does most of the work of a generic prepare. Kept as a separate method so that sub-classes can call it and get the StandardXAStatefulConnection back.

Throws:
javax.transaction.xa.XAException

prepare

public int prepare(javax.transaction.xa.Xid xid)
            throws javax.transaction.xa.XAException
Prepares to perform a commit. May actually perform a commit in the flag commitOnPrepare is set to true.

Specified by:
prepare in interface javax.transaction.xa.XAResource
Throws:
javax.transaction.xa.XAException

commit

public void commit(javax.transaction.xa.Xid xid,
                   boolean onePhase)
            throws javax.transaction.xa.XAException
Performs a commit on this resource manager's branch of the global transaction.

Specified by:
commit in interface javax.transaction.xa.XAResource
Throws:
javax.transaction.xa.XAException

rollback

public void rollback(javax.transaction.xa.Xid xid)
              throws javax.transaction.xa.XAException
PERFORMS a rollback on this resource manager's branch of the global transaction.

Specified by:
rollback in interface javax.transaction.xa.XAResource
Throws:
javax.transaction.xa.XAException

isSameRM

public boolean isSameRM(javax.transaction.xa.XAResource xares)
                 throws javax.transaction.xa.XAException
Specified by:
isSameRM in interface javax.transaction.xa.XAResource
Throws:
javax.transaction.xa.XAException

forget

public void forget(javax.transaction.xa.Xid xid)
            throws javax.transaction.xa.XAException
This is called by a TM when the RM has reported a heuristic completion. It must retain the transaction context until told to forget about it.

Specified by:
forget in interface javax.transaction.xa.XAResource
Throws:
javax.transaction.xa.XAException

recover

public javax.transaction.xa.Xid[] recover(int flag)
                                   throws javax.transaction.xa.XAException
Called by the transaction manager during recovery. If it was the transaction manager or another compoenent which failed then we can supply our known Xids. However if we failed then this method does nothing - we need to know about database internals to do that.

Specified by:
recover in interface javax.transaction.xa.XAResource
Throws:
javax.transaction.xa.XAException

setTransactionTimeout

public boolean setTransactionTimeout(int seconds)
Accessor methods for timeout.

Specified by:
setTransactionTimeout in interface javax.transaction.xa.XAResource

getTransactionTimeout

public int getTransactionTimeout()
Specified by:
getTransactionTimeout in interface javax.transaction.xa.XAResource

setCommitOnPrepare

public void setCommitOnPrepare(boolean commitOnPrepare)

getCommitOnPrepare

public boolean getCommitOnPrepare()

run

public void run()
Periodically checks for timed out connections.

Specified by:
run in interface java.lang.Runnable

getReference

public javax.naming.Reference getReference()
                                    throws javax.naming.NamingException
Specified by:
getReference in interface javax.naming.Referenceable
Throws:
javax.naming.NamingException

toString

public java.lang.String toString()
Overrides:
toString in class StandardPooledConnection