Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /*
    * JBoss, Home of Professional Open Source
    * Copyright 2006, Red Hat Middleware LLC, and individual contributors
    * as indicated by the @author tags.
    * See the copyright.txt in the distribution for a
    * full listing of individual contributors.
    * This copyrighted material is made available to anyone wishing to use,
    * modify, copy, or redistribute it subject to the terms and conditions
    * of the GNU Lesser General Public License, v. 2.1.
   * This program is distributed in the hope that it will be useful, but WITHOUT A
   * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
   * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
   * You should have received a copy of the GNU Lesser General Public License,
   * v.2.1 along with this distribution; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
   * MA  02110-1301, USA.
   *
   * (C) 2005-2009,
   * @author JBoss Inc.
   */
  /*
   * Copyright (C) 1998, 1999, 2000, 2001,
   *
   * Arjuna Solutions Limited,
   * Newcastle upon Tyne,
   * Tyne and Wear,
   * UK.
   *
   * $Id: ConnectionImple.java 2342 2006-03-30 13:06:17Z  $
   */
  
  package com.arjuna.ats.internal.jdbc;
  
  import java.sql.Array;
  import java.sql.Blob;
  import java.sql.Clob;
  import java.sql.NClob;
  import java.sql.SQLXML;
  import java.sql.Struct;
  import java.util.Map;
  
  import  javax.transaction.RollbackException;
  import  javax.transaction.Status;
  import  javax.transaction.SystemException;
  
A transactional JDBC connection. This wraps the real connection and registers it with the transaction at appropriate times to ensure that all worked performed by it may be committed or rolled back. Once a connection is used within a transaction, that instance is bound to that transaction for the duration. It can be used by any number of threads, as long as they all have the same notion of the "current" transaction. When the transaction terminates, the connection is freed for use in another transaction. Applications must not use this class directly.

Author(s):
Mark Little (mark@arjuna.com)
Version:
$Id: ConnectionImple.java 2342 2006-03-30 13:06:17Z $
Since:
JTS 2.0.
  
  
  public class ConnectionImple implements Connection
  {
  
  	public ConnectionImple(String dbNameProperties infothrows SQLException
  	{
  		if (..isTraceEnabled()) {
              ..trace("ConnectionImple.ConnectionImple ( " + dbName + " )");
          }
  
  		String user = null;
  		String passwd = null;
  		String dynamic = null;
  
  		if (info != null)
  		{
 		}
 
 		if ((dynamic == null) || (dynamic.equals("")))
 		{
 					userpasswdthis);
 		}
 		else
 		{
 					passwddynamicthis);
 		}
 
 		/*
 		 * Is there any "modifier" we are required to work with?
 		 */
 
 		 = null;
 		 = null;
 	}
 
 	public ConnectionImple(String dbNameString userString passwd)
 			throws SQLException
 	{
 		this(dbNameuserpasswdnull);
 	}
 
 	public ConnectionImple(String dbNameString userString passwd,
 			String dynamicthrows SQLException
 	{
 		if (..isTraceEnabled()) {
             ..trace("ConnectionImple.ConnectionImple ( " + dbName + ", " + user
                     + ", " + passwd + ", " + dynamic + " )");
         }
 
 		if ((dynamic == null) || (dynamic.equals("")))
 		{
 					userpasswdthis);
 		}
 		else
 		{
 					passwddynamicthis);
 		}
 
 		/*
 		 * Any "modifier" required to work with?
 		 */
 
 		 = null;
 		 = null;
 	}
 
 	{
 
 
 	}
 
 	public Statement createStatement(int rsint rcthrows SQLException
 	{
 
 
 		return getConnection().createStatement(rsrc);
 	}
 
 	{
 
 
 	}
 
 	public PreparedStatement prepareStatement(String sqlint rsint rc)
 			throws SQLException
 	{
 
 
 		return getConnection().prepareStatement(sqlrsrc);
 	}
 
 	{
 
 
 		return getConnection().prepareCall(sql);
 	}
 
 	public CallableStatement prepareCall(String sqlint rsint rc)
 			throws SQLException
 	{
 
 
 		return getConnection().prepareCall(sqlrsrc);
 	}
 
 	public String nativeSQL(String sqlthrows SQLException
 	{
 
 
 		return getConnection().nativeSQL(sql);
 	}
 
 	public Map getTypeMap() throws SQLException
 	{
 	}
 
 /*
     public void setTypeMap(Map map) throws SQLException
 	{
 		getConnection().setTypeMap(map);
 	}
 */
Not allowed if within a transaction.
 
 
 	public void setAutoCommit(boolean autoCommitthrows SQLException
 	{
 		{
 			if (autoCommit)
 		}
 		else
 		{
 		}
 	}
 
 	public boolean getAutoCommit() throws SQLException
 	{
 	}
 
 	public void commit() throws SQLException
 	{
 		/*
 		 * If there is a transaction running, then it cannot be terminated via
 		 * the driver - the user must go through current.
 		 */
 
 		{
 		}
 		else
 	}
 
 	public void rollback() throws SQLException
 	{
 		{
 		}
 		else
 	}
 
 	/*
 	 * This needs to be reworked in light of experience and requirements.
 	 */
 	public void close() throws SQLException
 	{
 	    try
 	    {
 	        /*
 	         * Need to know whether this particular connection has outstanding
 	         * resources waiting for it. If not then we can close, otherwise we
 	         * can't.
 	         */
 
 	        if (!.inuse())
 	        {
 	            ConnectionManager.remove(this); // finalize?
 	        }
 
 	        /*
 	         * Delist resource if within a transaction.
 	         */
 
 	        javax.transaction.TransactionManager tm = com.arjuna.ats.jta.TransactionManager
 	        .transactionManager();
 	        javax.transaction.Transaction tx = tm.getTransaction();
 
 	        /*
 	         * Don't delist if transaction not running. Rely on exception for
 	         * this. Also only delist if the transaction is the one the
 	         * connection is enlisted with!
 	         */
 
 	        boolean delayClose = false;
 
 	        if (tx != null)
 	        {
 	            if (.validTransaction(tx))
 	            {
 	                XAResource xares = .getResource();
 
 	                if (!tx.delistResource(xares.))
 	                    throw new SQLException(
 	                            ..get_delisterror());
 
 	                getModifier();
 
 	                if ( == null)
 	                {
                         ..info_closingconnectionnull(.toString());
 
 	                    // no indication about connections, so assume close immediately
 
 	                    if ( != null && !.isClosed())
 	                        .close();
 
 	                     = null;
 
 	                    return;
 	                }
 	                else
 	                {
 	                    if (((ConnectionModifier).supportsMultipleConnections())
 	                    {
 	                        /*
 	                         * We can't close the connection until the transaction has
 	                         * terminated, so register a Synchronization here.
 	                         */
 
                             ..warn_closingconnection(.toString());
 
 	                        delayClose = true;
 	                    }
 	                }
 
 	                if (delayClose)
 	                {
         	                tx.registerSynchronization(new ConnectionSynchronization());
 
                                  = null;
 	                }
 	            }
 	            else
 	                throw new SQLException(..get_closeerrorinvalidtx(tx.toString()));
 	        }
 
 	        if (!delayClose)  // close now
 	        {
 	            if ( != null && !.isClosed())
 	                .close();
 
 	             = null;
 	        }
 
 	        // what about connections without xaCon?
 	    }
 	    catch (IllegalStateException ex)
 	    {
 	        // transaction not running, so ignore.
 	    }
 	    catch (SQLException sqle)
 	    {
 	        throw sqle;
 	    }
 	    catch (Exception e1)
 	    {
 	        SQLException sqlException = new SQLException(..get_closeerror());
 	        sqlException.initCause(e1);
 	        throw sqlException;
 	    }
 	}
 
 	public boolean isClosed() throws SQLException
 	{
 		/*
 		 * A connection may appear closed to a thread if another thread has
 		 * bound it to a different transaction.
 		 */
 
 
 		if ( == null)
 			return false// not opened yet.
 		else
 	}
 
 	{
 	}

Can only set readonly before we use the connection in a given transaction!
 
 
 	public void setReadOnly(boolean rothrows SQLException
 	{
 		{
 		}
 		else
 	}
 
 	public boolean isReadOnly() throws SQLException
 	{
 	}
 
 	public void setCatalog(String catthrows SQLException
 	{
 
 
 	}
 
 	public String getCatalog() throws SQLException
 	{
 
 
 	}
 
 	public void setTransactionIsolation(int isothrows SQLException
 	{
 
 		/*
 		 * if (iso != Connection.TRANSACTION_SERIALIZABLE) throw new
 		 * SQLException(jdbcLogger.loggerI18N.getString.getString("com.arjuna.ats.internal.jdbc.stateerror")+"Connection.TRANSACTION_SERIALIZABLE");
 		 */
 
 	}
 
 	public int getTransactionIsolation() throws SQLException
 	{
 	}
 
 	public SQLWarning getWarnings() throws SQLException
 	{
 	}
 
 	public void clearWarnings() throws SQLException
 	{
 	}

Returns:
the Arjuna specific recovery connection information. This should not be used by anything other than Arjuna.
 
 
 	{
 	}
 
 	/*
 	 * ******************************************************************* *
 	 * JDBC 3.0 section
 	 */
 
     public void setTypeMap(Map<StringClass<?>> mapthrows SQLException
     {
         getConnection().setTypeMap(map);
     }
 
     public void setHoldability(int holdabilitythrows SQLException
     {
         checkTransaction();
 
         registerDatabase();
 
         getConnection().setHoldability(holdability);
     }
 
     public int getHoldability() throws SQLException
     {
         return getConnection().getHoldability();
     }
 
     public Savepoint setSavepoint() throws SQLException
     {
         if (transactionRunning())
         {
             throw new SQLException(..get_setsavepointerror());
         }
         else
         {
             return getConnection().setSavepoint();
         }
     }
 
     public Savepoint setSavepoint(String namethrows SQLException
     {
         if (transactionRunning())
         {
             throw new SQLException(..get_setsavepointerror());
         }
         else
         {
             return getConnection().setSavepoint(name);
         }
     }
 
     // The JDBC 3.0 spec (section 12.4) prohibits calling setSavepoint indide an XA tx.
     // It does not explicitly disallow calling rollback(savepoint) or releaseSavepoint(savepoint)
     // but allowing them does not make a whole lot of sense, so we don't:
 
 	public void rollback(Savepoint savepointthrows SQLException
 	{
 		{
 		}
 		else
 		{
 			getConnection().rollback(savepoint);
 		}
 	}
 
 	public void releaseSavepoint(Savepoint savepointthrows SQLException
 	{
 		{
 		}
 		else
 		{
 		}
 	}
 
 	public Statement createStatement(int resultSetTypeint resultSetConcurrency,
 									 int resultSetHoldabilitythrows SQLException
 	{
 
 
 		return getConnection().createStatement(resultSetTyperesultSetConcurrencyresultSetHoldability);
 	}
 
 	public PreparedStatement prepareStatement(String sqlint resultSetType,
 											  int resultSetConcurrencyint resultSetHoldabilitythrows SQLException
 	{
 
 
 		return getConnection().prepareStatement(sqlresultSetTyperesultSetConcurrencyresultSetHoldability);
 	}
 
 	public CallableStatement prepareCall(String sqlint resultSetType,
 										 int resultSetConcurrencyint resultSetHoldabilitythrows SQLException
 	{
 
 
 		return getConnection().prepareCall(sqlresultSetTyperesultSetConcurrencyresultSetHoldability);
 	}
 
 	public PreparedStatement prepareStatement(String sqlint autoGeneratedKeys)
 			throws SQLException
 	{
 
 
 		return getConnection().prepareStatement(sqlautoGeneratedKeys);
 	}
 
 	public PreparedStatement prepareStatement(String sqlint columnIndexes[])
 			throws SQLException
 	{
 
 
 		return getConnection().prepareStatement(sqlcolumnIndexes);
 	}
 
 	public PreparedStatement prepareStatement(String sqlString columnNames[])
 			throws SQLException
 	{
 
 
 		return getConnection().prepareStatement(sqlcolumnNames);
 	}
 
 	/*
 	 * end of the JDBC 3.0 section
 	 * *******************************************************************
 	 */
 
 
     /*
      * ******************************************************************* *
      * JDBC 4.0 method section.
      */
 
     public Clob createClob() throws SQLException
     {
         checkTransaction();
 
         registerDatabase();
 
         return getConnection().createClob();
     }
 
     public Blob createBlob() throws SQLException
     {
         checkTransaction();
 
         registerDatabase();
 
         return getConnection().createBlob();
     }
 
     public NClob createNClob() throws SQLException
     {
         checkTransaction();
 
 
     }
 
     public SQLXML createSQLXML() throws SQLException
     {
         checkTransaction();
 
 
     }
 
     public boolean isValid(int timeoutthrows SQLException
     {
         checkTransaction();
 
         registerDatabase();
 
         return getConnection().isValid(timeout);
     }
 
     public String getClientInfo(String namethrows SQLException
     {
         return getConnection().getClientInfo(name);
     }
 
     public Properties getClientInfo() throws SQLException
     {
         return getConnection().getClientInfo();
     }
 
     public void setClientInfo(String nameString valuethrows SQLClientInfoException
     {
         try
         {
     		getConnection().setClientInfo(namevalue);
         }
         catch(SQLException e)
         {
             throw new SQLClientInfoException("setClientInfo : getConnection failed"nulle);
         }
     }
 
     public void setClientInfo(Properties propertiesthrows SQLClientInfoException
     {
         try
         {
     		getConnection().setClientInfo(properties);
         }
         catch(SQLException e)
         {
             throw new SQLClientInfoException("setClientInfo : getConnection failed"nulle);
         }
     }
 
     public Array createArrayOf(String typeNameObject[] elementsthrows SQLException
     {
         checkTransaction();
 
         registerDatabase();
 
         return getConnection().createArrayOf(typeNameelements);
     }
 
     public Struct createStruct(String typeNameObject[] attributesthrows SQLException
     {
         checkTransaction();
 
         registerDatabase();
 
         return getConnection().createStruct(typeNameattributes);
     }
 
     public <T> T unwrap(Class<T> ifacethrows SQLException
     {
         if (iface != null) {
             if (iface.isInstance(this)) {
                 return (T) this;
             } else {
                 Connection conn = getConnection();
                 if (conn != null) {
                     if (iface.isInstance(conn)) {
                         return (T) conn;
                     } else if(conn.isWrapperFor(iface)) {
                         return conn.unwrap(iface);
                     }
                 }
             }
         }
         return null;
     }
 
     public boolean isWrapperFor(Class<?> ifacethrows SQLException
     {
         if (iface != null) {
             if (iface.isInstance(this)) {
                 return true;
             } else {
                 Connection conn = getConnection();
                 if (conn != null) {
                     if (iface.isInstance(conn)) {
                         return true;
                     } else {
                         return conn.isWrapperFor(iface);
                     }
                 }
             }
         }
         return false;
     }
 
     /*
 	 * end of the JDBC 4.0 section
 	 * *******************************************************************
 	 */
 
     /*
      * ******************************************************************* *
      * Java 7 method section.
      */
 
     //@Override
     public void setSchema(String schemathrows SQLException
     {
         throw new SQLException();
     }
 
     //@Override
     public String getSchema() throws SQLException
     {
         throw new SQLException();
     }
 
     //@Override
     public void abort(Executor executorthrows SQLException
     {
         throw new SQLException();
     }
 
     //@Override
     public void setNetworkTimeout(Executor executorint millisecondsthrows SQLException
     {
         throw new SQLException();
     }
 
     //@Override
     public int getNetworkTimeout() throws SQLException
     {
         throw new SQLException();
     }
 
     /*
 	 * end of the Java 7 section
 	 * *******************************************************************
 	 */


    

Returns:
the XAResource associated with the current XAConnection.
 
 
 	protected final XAResource getXAResource()
 	{
 		try
 		{
 		}
 		catch (Exception e)
 		{
 			return null;
 		}
 	}

Remove this connection so that we have to get another one when asked. Some drivers allow connections to be reused once any transactions have finished with them.
 
 
 	final void reset()
 	{
 		try
 		{
 			if ( != null)
 		}
 		catch (Exception ex)
 		{
 		}
 		finally
 		{
 			 = null;
 		}
 	}
 
 	{
 		if ( != null && !.isClosed())
 			return ;
 
 
 		if (xaConn != null)
 		{
 
 			try
 			{
 
 				if ( != null)
 				{
 				}
 			}
 			catch (SQLException ex)
 			{
 				throw ex;
 			}
 			catch (Exception e)
 			{
                 ..warn_isolationlevelfailset("ConnectionImple.getConnection"e);
 
                 SQLException sqlException = new SQLException(..get_conniniterror());
                 sqlException.initCause(e);
                 throw sqlException;
 			}
 
 			return ;
 		}
 		else
 			return null;
 	}
 
 	{
 	}
 
 	protected final boolean transactionRunning() throws SQLException
 	{
 		try
 		{
 			if (com.arjuna.ats.jta.TransactionManager.transactionManager()
 					.getTransaction() != null)
 			{
 				return true;
 			}
 			else
 			{
 				return false;
 			}
 		}
 		catch (Exception e)
 		{
             SQLException sqlException = new SQLException(e.toString());
             sqlException.initCause(e);
             throw sqlException;
 		}
 	}

Whenever a JDBC call is invoked on us we get an XAResource and try to register it with the transaction. If the same thread causes this to happen many times within the same transaction then we will currently attempt to get and register many redundant XAResources for it. The JTA implementation will detect this and ignore all but the first for each thread. However, a further optimisation would be to trap such calls here and not do a registration at all. This would require the connection object to be informed whenever a transaction completes so that it could flush its cache of XAResources though.
 
 
 	protected final synchronized void registerDatabase() throws SQLException
 	{
 		if (..isTraceEnabled()) {
             ..trace("ConnectionImple.registerDatabase ()");
         }
 
 		Connection theConnection = getConnection();
 
 		if (theConnection != null)
 		{
 			XAResource xares = null;
 
 			try
 			{
 				javax.transaction.TransactionManager tm = com.arjuna.ats.jta.TransactionManager
 				javax.transaction.Transaction tx = tm.getTransaction();
 
 				if (tx == null)
 					return;
 
 				/*
 				 * Already enlisted with this transaction?
 				 */
 
 
 				Object[] params;
 
 				if ( != null)
 					params = new Object[2];
 				else
 					params = new Object[1];
 
 
 				if ( != null)
 
 				/*
 				 * Use our extended version of enlistResource.
 				 */
 
 
 						.enlistResource(xaresparams))
 				{
 					/*
 					 * Failed to enlist, so mark transaction as rollback only.
 					 */
 
 					try
 					{
 						tx.setRollbackOnly();
 					}
 					catch (Exception e)
 					{
                         ..warn_rollbackerror("ConnectionImple.registerDatabase");
 
                         SQLException sqlException = new SQLException(e.toString());
                         sqlException.initCause(e);
 						throw sqlException;
 					}
 
 					throw new SQLException(
 							"ConnectionImple.registerDatabase - "
				params = null;
				xares = null;
				tx = null;
				tm = null;
			catch (RollbackException e1)
                SQLException sqlException = new SQLException("ConnectionImple.registerDatabase - " + e1);
                sqlException.initCause(e1);
				throw sqlException;
			catch (SystemException e2)
                SQLException sqlException = new SQLException("ConnectionImple.registerDatabase - "e2);
                sqlException.initCause(e2);
                throw sqlException;
			catch (SQLException e3)
				throw e3;
			catch (Exception e4)
                SQLException sqlException = new SQLException(e4.toString());
                sqlException.initCause(e4);
                throw sqlException;
	protected final void checkTransaction() throws SQLException
		if (..isTraceEnabled()) {
            ..trace("ConnectionImple.checkTransaction ()");
        }
		try
			javax.transaction.TransactionManager tm = com.arjuna.ats.jta.TransactionManager
			javax.transaction.Transaction tx = tm.getTransaction();
			if (tx == null)
				return;
			if (tx.getStatus() != Status.STATUS_ACTIVE)
			/*
			 * Now check that we are not already associated with a transaction.
			 */
				throw new SQLException(
		catch (SQLException ex)
			throw ex;
		catch (Exception e3)
            SQLException sqlException = new SQLException(..get_infoerror());
            sqlException.initCause(e3);
            throw sqlException;
	private final void getModifier()
		if ( == null)
			try
				String name = md.getDriverName();
				int major = md.getDriverMajorVersion();
				int minor = md.getDriverMinorVersion();
				 = ModifierFactory.getModifier(namemajorminor);
			catch (Exception ex)
                ..warn_getmoderror(ex);
	static
         = jdbcPropertyManager.getJDBCEnvironmentBean().getIsolationLevel();