<?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="next.html">Next</link>
			</links>
			<links include="includes/trailmap_additional.xml"/>
		</navigation>
		<area title="The banking application as a relational database accessed with JDBC">
			<html>
				<p>In regards to the its structure in the previous trails, the banking application
  described here has been slightly simplified. In this version creating local
  JTA transactions, accounts managed by a bank object are in fact instances or
  tuples within a SQL relational table named &quot;accounts&quot;. When the Bank
  object is requested for instance to create an account or to get information
  on an account, the Bank object performs SQL statement such SQL INSERT or SQL
  SELECT.</p>
				<h4>Deploy the application</h4>
				<p>Executing the demonstration consists to launch the folowing program</p>
				<pre>
					<font face="Courier New, Courier, mono">java com.arjuna.demo.jta.jdbcbank.BankClient  -host &lt;hostName&gt;
  -port portNumber  -username &lt;userName&gt;  -dbName &lt;DBName&gt;
  -password &lt;password&gt; -clean|-create</font>
				</pre>
  Where:
		<ul>
					<li>hostName - the name of the machine where is located the database</li>
					<li>userName - the user name used to access the database</li>
					<li>password - the password used to access to database</li>
					<li>DBName   - the database name</li>
					<li>clean    - the existing relational table will be deleted then created</li>
					<li>create   - a new relational table will be created</li>
				</ul>

<p><i>Note</i> Due to an issue with Oracle, it is possible that an XA exception is thrown when attempting to perform this test (see Release Notes).
If an xa error is returned you can use the following property property <i>com.arjuna.ats.jdbc.isolationLevel </i> set to <i>TRANSACTION_READ_COMMITTED</i>.<br/>
This property can be added in previous command as follow:
</p>
<pre>
<font face="Courier New, Courier, mono">java -Dcom.arjuna.ats.jdbc.isolationLevel=TRANSACTION_READ_COMMITTED
     com.arjuna.demo.jta.jdbcbank.BankClient  -host &lt;hostName&gt;
    -port portNumber  -userName &lt;userName&gt;
    -password &lt;password&gt; -clean|-create</font>
</pre>



<h4>How JDBC is used</h4>
<p>The following Banking application illustrates some methods that use the JDBC API. In this application, the way
  to create a jdbc connection is made via an XADataSource obtained with JNDI operations, es explained in the previous
  trail <a class="linkscoloured" href="part6_jdbc_banking.html">jdbc introduction</a>
  The BankClient class instantiates an XADataSource and bind it to a jndi naming in order to be retrieved to create
  transactional connections. <b/>
  This portion of code illustrates how this made against oracle (tested on version 9i). A similar code could tested
  against an other database by providng the appropriate XADataSource implementation. Details of the BankClient class
  can be found in the file <a class="linkscoloured" href="../src/com/arjuna/demo/jta/jdbcbank/BankClient.java">BankClient.java</a>
  <pre>
  package com.arjuna.demo.jta.jdbcbank;

  import javax.naming.*;
  import java.util.Hashtable;
  import oracle.jdbc.xa.client.OracleXADataSource;
  import com.arjuna.ats.jdbc.common.jdbcPropertyManager;

  public class BankClient
  {
   .....
   public static void main(String[] args)
    {
      //Provide the apporopriate information to access the database
      for (int i = 0; i &lt; args.length; i++)
      {
          if (args[i].compareTo("-host") == 0)
              host = args[i + 1]
		  if (args[i].compareTo("-port") == 0)
                port = args[i + 1];
		  if (args[i].compareTo("-username") == 0)
                user = args[i + 1];
          if (args[i].compareTo("-password") == 0)
                password = args[i + 1];
	      if (args[i].compareTo("-dbName") == 0)
                dbName = args[i + 1];
          ....
      }

     try
     {
       // create DataSource
       OracleXADataSource ds = new OracleXADataSource();
       ds.setURL("jdbc:oracle:thin:@"+host+":"+port+":"+dbName);

       // now stick it into JNDI
       Hashtable env = new Hashtable();
       env.put (Context.INITIAL_CONTEXT_FACTORY,
	   "com.sun.jndi.fscontext.RefFSContextFactory");
	    env.put (Context.PROVIDER_URL, "file:/tmp/JNDI");
	    InitialContext ctx = new InitialContext(env);
	    ctx.rebind("jdbc/DB", ds);
     }
	 catch (Exception ex)
	 { }
  	 //Set the jndi information to be user by the Arjuna JDBC Property Manager
	 jdbcPropertyManager.propertyManager.setProperty("Context.INITIAL_CONTEXT_FACTORY",
	   "com.sun.jndi.fscontext.RefFSContextFactory");
	 jdbcPropertyManager.propertyManager.setProperty("Context.PROVIDER_URL",
	   "file:/tmp/JNDI");

	 Bank bank = new Bank();
     BankClient client = new BankClient(bank);

   }
  </pre>

 </p>
 <p>
  While the BankClient class is responsible to obtain information to access the database, tocreate the XADataSource
  and bind it to jndi, and also to get order from a user (create_account, debit, transfer, ..), the Bank class is resposnible
  to create jdbc connections to perform user's requests. The Bank class is illustarted below where.  All
   methods are not illusrated here but have a similar behavior; they could be found in
  details in the <a class="linkscoloured" href="../src/com/arjuna/demo/jta/jdbcbank/Bank.java">Bank.java</a>
  program. Note that for simplicity, much error checking code has been removed.</p>
<pre>public Bank()
{
  try
  {
    DriverManager.registerDriver(new TransactionalDriver());
    dbProperties = new Properties();
    dbProperties.put(TransactionalDriver.userName, user);
    dbProperties.put(TransactionalDriver.password, password);
    arjunaJDBC2Driver = new TransactionalDriver(); //
	create_table();
  }
   catch (Exception e)
   {
   e.printStackTrace();
   System.exit(0);
   }

   _accounts = new java.util.Hashtable();
   reuseConnection = true;
   }

   public void create_account( String _name, float _value )
   {
    try
    {
	  Connection conne = arjunaJDBC2Driver.connect("jdbc:arjuna:jdbc/DB", dbProperties);
      Statement stmtx = conne.createStatement(); // tx statement
      stmtx.executeUpdate
        (&quot;INSERT INTO accounts (name, value)
          VALUES ('&quot;+_name+&quot;',&quot;+_value+&quot;)&quot;);
    }
    catch (SQLException e)
    {
      e.printStackTrace();
    }
   }

  public float get_balance(String _name)
     throws NotExistingAccount
  {
    float theBalance = 0;
    try
    {
	  Connection conne = arjunaJDBC2Driver.connect("jdbc:arjuna:jdbc/DB", dbProperties);
      Statement stmtx = conne.createStatement(); // tx statement
      ResultSet rs = stmtx.executeQuery
         (&quot;SELECT value from accounts
           WHERE name    = '&quot;+_name+&quot;'&quot;);
      while (rs.next()) {
        theBalance = rs.getFloat(&quot;value&quot;);
      }
    }
    catch (SQLException e)
    {
      e.printStackTrace();
      throw new NotExistingAccount(&quot;The Account requested does not exist&quot;);
    }
    return theBalance;
  }

 ...
}
</pre>
				<h4>Note</h4>
				<p>Although, this version of the banking application creates JTA local transactions,
  the way to manipulate JDBC API and the associated JBossTS mechanisms in the
  case of distributed transactions is the same.</p>
			</html>
		</area>
	</content>
	<footer/>
</page>
