<?xml version="1.0"?>
<!--
  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-2006,
  @author JBoss Inc.
-->
<page title="JBossTS 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 JBossTS JTS">
			<html>
				<p>JBossTS JTS supports the construction of both local and distributed transactional
  applications which access databases using the JDBC APIs. JDBC supports
  two-phase commit of transactions, and is similar to the XA X/Open standard.
  The JDBC support is found in the com.arjuna.ats.jdbc package.</p>
				<h4>Transactional Driver</h4>
				<p>The JBossTS JTS 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, JBossTS
  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 JBossTS 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 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, JBossTS
      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. JBossTS therefore has several classes
      which are for specific JDBC 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 JBossTS. Once
  created, the driver and any connection can be used in the same way as any other
  JDBC driver or connection.</p>
				<p> JBossTS 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. JBossTS 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> JBossTS 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 JBossTS Programming Guide.</p>
			</html>
		</area>
	</content>
	<footer/>
</page>
