<?xml version="1.0"?>
<!--
  JBoss, Home of Professional Open Source
  Copyright 2006, JBoss Inc., and individual contributors as indicated
  by the @authors tag.  All rights reserved. 
  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 General Public License, v. 2.0.
  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 General Public License for more details.
  You should have received a copy of the GNU General Public License,
  v. 2.0 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-2006,
  @author JBoss Inc.
-->
<page title="Arjuna Technologies Limited: Trail map: Running and Testing Examples" rootpath="../..">
	<header>         Making the Banking Application Persistent   </header>
	<content>
		<navigation>
			<links include="includes/www_arjuna_com_navigation.xml"/>
			<links include="includes/trailmap_navigation.xml"/>
			<links title="Navigation">
				<link ref="index.html">Home</link>
				<link ref="part6.html">Previous</link>
				<link ref="part6_jdbc_banking.html">Next</link>
			</links>
			<links include="includes/trailmap_additional.xml"/>
		</navigation>
		<area title="Developing applications with JDBC and ArjunaJTS">
			<html>
				<p>ArjunaJTS supports the construction of both local and distributed transactional 
  applications which access databases using the JDBC 2.0 APIs. JDBC 2.0 supports 
  two-phase commit of transactions, and is similar to the XA X/Open standard. 
  The JDBC 2.0 support is found in the com.arjuna.ats.jdbc package.</p>
				<h4>Transactional Driver</h4>
				<p>The ArjunaJTS approach to incorporating JDBC connections within transactions 
  is to provide transactional JDBC drivers through which all interactions occur. 
  These drivers intercept all invocations and ensure that they are registered 
  with, and driven by, appropriate transactions. There is a single type of transactional 
  driver through which any JDBC driver can be driven; obviously if the database 
  is not transactional then ACID properties cannot be guaranteed. This driver 
  is com.arjuna.ats.jdbc.TransactionalDriver, which implements the java.sql.Driver 
  interface.</p>
				<p>The driver may be directly instantiated and used within an application. For 
  example:</p>
				<pre> TransactionalDriver arjunaJDBC2Driver = new TransactionalDriver(); </pre>
				<p>It can be registered with the JDBC driver manager (java.sql.DriverManager) 
  by adding them to the Java system properties. The jdbc.drivers property contains 
  a list of driver class names, separated by colons, that are loaded by the JDBC 
  driver manager when it is initialised, for instance:</p>
			
<pre>jdbc.drivers=foo.bar.Driver:mydata.sql.Driver:bar.test.myDriver</pre>

				<p> On running an application, it is the DriverManager's responsibility to load 
  all the drivers found in the system property jdbc.drivers. For example, this 
  is where the driver for the Oracle database may be defined. When opening a connection 
  to a database it is the DriverManager' s role to choose the most appropriate 
  driver from the previously loaded drivers. </p>
				<p> A program can also explicitly load JDBC drivers at any time. For example, 
  the my.sql.Driver is loaded with the following statement: </p>

<pre>Class.forName(&quot;my.sql.Driver&quot;); </pre>

				<p>Calling Class.forName() will automatically register the driver with the JDBC 
  driver manager. It is also possible to explicitly create an instance of the 
  JDBC driver using the registerDriver method of the DriverManager. This is the 
  case for instance for the TransactionalDriver that can be registered as follow:</p>

<pre>TransactionalDriver arjunaJDBC2Driver = new TransactionalDriver(); 
DriverManager.registerDriver(arjunaJDBC2Driver);</pre>

				<p> When you have loaded a driver, it is available for making a connection with 
  a DBMS.</p>
				<h4>Making Connections</h4>
				<p>Once a driver is loaded and ready for a connection to be made, instances of 
  a Connection class can be created using the getConnection method on the DriverManager, 
  as follow:</p>

<pre>Connection con = DriverManager.getConnection(url, username, password);</pre>

				<p>From its version 2.0, the JDBC API has introduced a new way to obtain instances 
  of the Connection class. This is the case of the interfaces DataSource and XADataSource 
  that creates transactional connections. When using a JDBC 2.0 driver, ArjunaTA 
  will use the appropriate DataSource whenever a connection to the database is 
  made. It will then obtain XAResources and register them with the transaction 
  via the JTA interfaces. It is these XAResources which the transaction service 
  will use when the transaction terminates in order to drive the database to either 
  commit or rollback the changes made via the JDBC connection.</p>
				<p> There are two ways in which the ArjunaTA JDBC 2.0 support can obtain XADataSources. 
  These will be explained in the following sections. Note, for simplicity we shall 
  assume that the JDBC 2.0 driver is instantiated directly by the application.</p>
				<ol>
					<li>
						<p>Java Naming and Directory Interface (JNDI)</p>
						<p> To get the ArjunaJDBC2Driver class to use a JNDI registered XADataSource 
      it is first necessary to create the XADataSource instance and store it in 
      an appropriate JNDI implementation. Details of how to do this can be found 
      in the JDBC 2.0 tutorial available at JavaSoft. An example is show below:</p>
						<pre>XADataSource ds = MyXADataSource();
Hashtable env = new Hashtable();
String initialCtx = PropertyManager.
  getProperty(&quot;Context.INITIAL_CONTEXT_FACTORY&quot;);
env.put(Context.INITIAL_CONTEXT_FACTORY, initialCtx);
initialContext ctx = new InitialContext(env);
ctx.bind(&quot;jdbc/foo&quot;, ds);</pre>
						<p> Where the Context.INITIAL_CONTEXT_FACTORY property is the JNDI way of 
      specifying the type of JNDI implementation to use.<br/>
      Then the application must pass an appropriate connection URL to the JDBC 
      2.0 driver:</p>
						<pre>Properties dbProps = new Properties();
dbProps.setProperty(TransactionalDriver.userName, &quot;user&quot;);
dbProps.setProperty(TransactionalDriver.password, &quot;password&quot;);
TransactionalDriver arjunaJDBC2Driver = new TransactionalDriver();
Connection connection = arjunaJDBC2Driver.
  connect(&quot;jdbc:arjuna:jdbc/foo&quot;, dbProps);</pre>
						<p> The JNDI URL must be pre-pended with <font face="Courier New, Courier, mono">jdbc:arjuna:</font> 
      in order for the ArjunaJDBC2Driver to recognise that the DataSource must 
      participate within transactions and be driven accordingly. </p>
					</li>
					<li>
						<p>Dynamic class instantiation</p>
						<p> Many JDBC 2.0 implementations provide proprietary implementations of XADataSources 
      that provide non-standard extensions to the specification. In order to allow 
      the application to remain isolated from the actual JDBC 2.0 implementation 
      it is using and yet continue to be able to use these extensions, ArjunaTA 
      hides the details of these proprietary implementations using dynamic class 
      instantiation. In addition, the use of JNDI is not required when using this 
      mechanism because the actual implementation of the XADataSource will be 
      directly instantiated, albeit in a manner which will not tie an application 
      or driver to a specific implementation. ArjunaTA therefore has several classes 
      which are for specific JDBC 2.0 implementations, and these can be selected 
      at runtime by the application setting the dynamicClass property appropriately: 
    </p>
					</li>
				</ol>
				<blockquote>
					<table width="60%" border="1">
						<tr>
							<td width="26%">
								<strong>Database Type</strong>
							</td>
							<td width="74%">
								<strong>Property Name</strong>
							</td>
						</tr>
						<tr>
							<td>Cloudscape 3.6</td>
							<td>com.arjuna.ats.internal.jdbc.drivers.cloudscape_3_6</td>
						</tr>
						<tr>
							<td>Sequelink 5.1</td>
							<td>com.arjuna.ats.internal.jdbc.drivers.sequelink_5_1</td>
						</tr>
						<tr>
							<td>Oracle 8.1.6</td>
							<td>com.arjuna.ats.internal.jdbc.drivers.oracle_8_1_6</td>
						</tr>
						<tr>
							<td>SQL Server 2000</td>
							<td>com.arjuna.ats.internal.jdbc.drivers.sqlserver_2_2</td>
						</tr>
					</table>
				</blockquote>
				<blockquote>
					<p>The application code must specify which dynamic class the TransactionalDriver 
    should instantiate when setting up the connection:</p>
				</blockquote>
				<ul>
					<pre>Properties dbProps = new Properties();
dbProps.setProperty(TransactionalDriver.userName, &quot;user&quot;);
dbProps.setProperty(TransactionalDriver.password, &quot;password&quot;);
dbProps.setProperty(TransactionalDriver.dynamicClass,
    &quot;com.arjuna.ats.internal.jdbc.drivers.sequelink_5_0&quot;);
TransactionalDriver arjunaJDBC2Driver = new TransactionalDriver();
Connection connection = arjunaJDBC2Driver.connect(&quot;jdbc:arjuna:
    sequelink://host:port;databaseName=foo&quot;,dbProperties);
</pre>
				</ul>
				<p>Note on properties used by the com.arjuna.ats.jdbc.TransactionalDriver class</p>
				<ul>
					<li>
						<em>userName</em>: the user name to use when attempting to connect to the 
    database.</li>
					<li>
						<em>password</em>: the password to use when attempting to connect to the 
    database.</li>
					<li>
						<em>createDb</em>: if set to true, the driver will attempt to create the 
    database when it connects. This may not be supported by all JDBC 2.0 implementations.</li>
					<li>
						<em>dynamicClass</em>: this specifies a class to instantiate to connect 
    to the database, rather than using JNDI.</li>
				</ul>
				<h4> Using the Connection</h4>
				<p>Once the connection has been established (for example, using the java.sql.DriverManager.getConnection 
  method), all operations on the connection will be monitored by ArjunaTA. Once 
  created, the driver and any connection can be used in the same way as any other 
  JDBC driver or connection.</p>
				<p> ArjunaTA connections can be used within multiple different transactions simultaneously, 
  i.e., different threads, with different notions of the current transaction, 
  may use the same JDBC connection. ArjunaTA does connection pooling for each 
  transaction within the JDBC connection. So, although multiple threads may use 
  the same instance of the JDBC connection, internally this may be using a different 
  connection instance per transaction. With the exception of close, all operations 
  performed on the connection at the application level will only be performed 
  on this transaction-specific connection.</p>
				<p> ArjunaTA will automatically register the JDBC driver connection with the transaction 
  via an appropriate resource . When the transaction terminates, this resource 
  will be responsible for either committing or rolling back any changes made to 
  the underlying database via appropriate calls on the JDBC driver.</p>
				<h4>Further reading</h4>
				<p>More details on the way to manage applications using the JDBC API can be found 
  in the ArjunaTA Programming Guide.</p>
			</html>
		</area>
	</content>
	<footer/>
</page>
