[jboss-svn-commits] JBL Code SVN: r35930 - in labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US: extras and 1 other directory.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Wed Nov 10 01:52:56 EST 2010


Author: misty at redhat.com
Date: 2010-11-10 01:52:56 -0500 (Wed, 10 Nov 2010)
New Revision: 35930

Added:
   labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/class.forName.java
   labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/creating_and_using_a_connection.java
   labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/failure_recovery_example.java
   labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/instantiating_dynamic_class.java
   labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/instantiating_transactional_driver.java
   labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/jdbc_example.java
   labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/jrmp_invoker_proxy.java
   labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/passing_connection_url_to_jdbc.java
   labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/registering_transactionaldriver_using_jdbc_driver_manager.java
   labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/storing_datasource_in_jndi.java
Modified:
   labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/Configuring_JBossTA.xml
   labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/Examples.xml
   labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/JDBC.xml
   labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/Using_JBossTA_In_Application_Servers.xml
Log:
Finished initial conversion of JTA Development Guide

Modified: labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/Configuring_JBossTA.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/Configuring_JBossTA.xml	2010-11-10 04:42:27 UTC (rev 35929)
+++ labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/Configuring_JBossTA.xml	2010-11-10 06:52:56 UTC (rev 35930)
@@ -4,6 +4,39 @@
 %BOOK_ENTITIES;
 ]>
 <chapter>
-  <title></title>
+  <title>Configuring JBossJTA</title>
+  
+  <section>
+    <title>Configuration loading mechanism</title>
+    <para>
+      In general, configuration is managed the same as ArjunaCore. Refer to the <citetitle>ArjunaCore Development
+      Guide</citetitle> for more information.
+    </para>
+    
+  </section>
+  
+  <section>
+    <title>Configuration options</title>
+    <para>
+      The canonical reference for configuration options is the javadoc of the various EnvironmentBean classes. For
+      ArjunaJTA, these classes are the ones provided by ArjunaCore, as well as:
+    </para>
+    <itemizedlist>
+      <listitem>
+        <para>
+          com.arjuna.ats.jdbc.common.JDBCEnvironmentBean.java
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          com.arjuna.ats.jta.common.JTAEnvironmentBean.java
+        </para>
+      </listitem>
+    </itemizedlist>
+    <para>
+      Modules built on ArjunaCore and ArjunaJTA may add additional beans. Please refer to the relevant Development
+      Guides for details of these.
+    </para>
+  </section>
 </chapter>
 

Modified: labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/Examples.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/Examples.xml	2010-11-10 04:42:27 UTC (rev 35929)
+++ labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/Examples.xml	2010-11-10 06:52:56 UTC (rev 35930)
@@ -4,6 +4,58 @@
 %BOOK_ENTITIES;
 ]>
 <chapter>
-  <title></title>
+  <title>Examples</title>
+  
+  <section>
+    <title>JDBC example</title>
+
+    <example>
+      <title>JDBC example</title>
+      <para>
+        This simplified example assumes that you are using the transactional JDBC driver provided with JBossTS. For
+        details about how to configure and use this driver see the previous Chapter.<!-- Link? -->
+      </para>
+      <programlisting language="Java" role="JAVA"><xi:include href="extras/jdbc_example.java" xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" /></programlisting>
+    </example>
+  </section>
+
+  <section>
+    <title>Failure recovery example with BasicXARecovery</title>
+    <para>
+      This class implements the <interfacename>XAResourceRecovery</interfacename> interface for XAResources. The parameter supplied in <varname>setParameters</varname>
+      can contain arbitrary information necessary to initialize the class once created. In this example, it contains the
+      name of the property file in which the database connection information is specified, as well as the number of
+      connections that this file contains information on. Each item is separated by a semicolon.
+    </para>
+    <para>
+      This is only a small example of the sorts of things an XAResourceRecovery implementer could do. This implementation
+      uses a property file that is assumed to contain sufficient information to recreate connections used during the
+      normal run of an application so that recovery can be performed on them. Typically, usernames and passwords should
+      never be presented in raw text on a production system.
+    </para>
+    <example>
+      <title>Database parameter format for the properties file</title>
+      <screen>
+ DB_x_DatabaseURL=
+ DB_x_DatabaseUser=
+ DB_x_DatabasePassword=
+ DB_x_DatabaseDynamicClass=
+      </screen>
+      <para>
+        <replaceable>x</replaceable> is the number of the connection information.
+      </para>
+    </example>
+    <para>
+      Some error-handling code is missing from this example, to make it more readable.
+    </para>
+    <example>
+      <title>Failure recovery example with BasicXARecovery</title>
+      <programlisting language="Java" role="JAVA"><xi:include href="extras/failure_recovery_example.java" xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" /></programlisting>
+      <para>
+        You can use the class <classname>com.arjuna.ats.internal.jdbc.recovery.JDBC2RecoveryConnection</classname> to
+        create a new connection to the database using the same parameters used to create the initial connection.
+      </para>
+    </example>
+  </section>
 </chapter>
 

Modified: labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/JDBC.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/JDBC.xml	2010-11-10 04:42:27 UTC (rev 35929)
+++ labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/JDBC.xml	2010-11-10 06:52:56 UTC (rev 35930)
@@ -4,6 +4,307 @@
 %BOOK_ENTITIES;
 ]>
 <chapter>
-  <title></title>
+  <title>JDBC and Transactions</title>
+  
+  <section>
+    <title>Using the transactional JDBC driver</title>
+    <para>
+      JBossJTA supports 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. JBossTS provides JDBC support in package <package>com.arjuna.ats.jdbc</package>. A list of the tested
+      drivers is available from the JBossTS website.<!-- Put this in an appendix? Link directly to it? -->
+    </para>
+    <para>
+      Only use the transactional JDBC support provided in package <package>com.arjuna.ats.jdbc</package> when you are
+      using JBossTS outside of an application server, such as JBoss Application Server, or another container. Otherwise,
+      use the JDBC support provided by your application server or container.
+    </para>
+    <section>
+      <title>Managing transactions</title>
+      <para>
+        JBossJTA needs the ability to associate work performed on a JDBC connection with a specific
+        transaction. Therefore, applications need to use a combination of implicit transaction propagation and indirect
+        transaction management. For each JDBC connection, JBossJTA must be able to determine the invoking thread's
+        current transaction context.
+      </para>
+    </section>
+    <section>
+      <title>Restrictions</title>
+      <para>
+        Nested transactions are not supported by JDBC. If you try to use a JDBC connection within a subtransaction,
+        JBossJTA throws a suitable exception and no work is allowed on that connection. However, if you need nested
+        transactions, and are comfortable with straying from the JDBC standard, you can set property
+        <varname>com.arjuna.ats.jta.supportSubtransactions</varname> property to <literal>YES</literal>.
+      </para>
+    </section>
+  </section>
+  
+  <section>
+    <title>Transactional drivers</title>
+    <para>
+      The approach JBossJTA takes for incorporating JDBC connections within transactions is to provide transactional
+      JDBC drivers as conduits for all interactions. These drivers intercept all invocations and ensure that they are
+      registered with, and driven by, appropriate transactions. The driver
+      <classname>com.arjuna.ats.jdbc.TransactionalDriver</classname> handles all JDBC drivers, implementing the
+      <interfacename>java.sql.Driver</interfacename> interface. If the database is not transactiona, ACID properties
+      cannot be guaranteed.
+    </para>
+    <section>
+      <title>Loading drivers</title>
+      <example>
+        <title>Instantiating and using the driver within an application</title>
+        <programlisting language="Java" role="JAVA"><xi:include href="extras/instantiating_transactionaldriver.java" xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" /></programlisting>
+      </example>
+
+      <example>
+        <title>Registering the drivers with the JDBC driver manager using the Java system properties</title>
+        <programlisting language="Java" role="JAVA">
+        <xi:include href="extras/registering_transactionaldriver_using_jdbc_driver_manager.java" xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" /></programlisting>
+        <para>
+          The jdbc.drivers property contains a colon-separated list of driver class names, which the JDBC driver manager
+          loads when it is initialized.  After the driver is loaded, you can use it to make a connection wtih a
+          database.
+        </para>
+      </example>
+      <example>
+        <title>Using the <methodname>Class.forName</methodname> method</title>
+        <para>
+          Calling <methodname>Class.forName()</methodname> automatically registers the driver with the JDBC driver
+          manager. It is also possible to explicitly create an instance of the JDBC driver.
+        </para>
+        <programlisting language="Java" role="JAVA"><xi:include href="extras/class.forName.java" xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" /></programlisting>
+      </example>
+    </section>
+  </section>
+
+  
+  <section>
+    <title>Connections</title>
+    <para>
+      Because JBossJTA provides JDBC connectivity via its own JDBC driver, application code can support transactions
+      witho relatively small code chnges. Typically, the application programmer only needs to start and terminate
+      transactions.
+    </para>
+    <section>
+      <title>JDBC</title>
+      <para>
+        The JBossJTA driver accepts the following properties, all located in class
+        <classname>com.arjuna.ats.jdbc.TransactionalDriver</classname>.
+      </para>
+      <informaltable>
+        <tgroup cols="2">
+          <tbody>
+            <row>
+              <entry>username</entry>
+              <entry>
+                <para>
+                  the database username
+                </para>
+              </entry>
+            </row>
+            <row>
+              <entry>password</entry>
+              <entry>
+                <para>
+                  the database password
+                </para>
+              </entry>
+            </row>
+            <row>
+              <entry>createDb</entry>
+              <entry>
+                <para>
+                  creates the database automatically if set to <literal>true</literal>. Not all JDBC implementations
+                  support this.
+                </para>
+              </entry>
+            </row>
+            <row>
+              <entry>dynamicClass</entry>
+              <entry>
+                <para>
+                  specifies a class to instantiate to connect to the database, instead of using JNDI.
+                </para>
+              </entry>
+            </row>
+          </tbody>
+        </tgroup>
+      </informaltable>
+    </section>
+    <section>
+      <title>XADataSources</title>
+      <para>
+        JDBC connections are created from appropriate DataSources. Connections which participate in distributed
+        transactions are obtained from XADataSources. When using a JDBC driver, JBossJTA uses the appropriate DataSource
+        whenever a connection to the database is made. It then obtains XAResources and registers them with the
+        transaction via the JTA interfaces. The transaction service uses these XAResources when the transaction
+        terminates in order to drive the database to either commit or roll back the changes made via the JDBC
+        connection.
+      </para>
+      <para>
+        JBossJTA JDBC support can obtain XADataSources through the Java Naming and Directory Interface (JNDI) or dynamic
+        class instnatiation.
+      </para>
+      <section>
+        <title>Java naming and directory interface (JNDI)</title>
+        <para>
+          A JDBC driver can use arbitrary DataSources without having to know specific details about their
+          implementations, by using JNDI. A specific DataSource or XADataSource can be created and registered with an
+          appropriate JNDI implementation, and the application, or JDBC driver, can later bind to and use it. Since JNDI
+          only allows the application to see the DataSource or XADataSource as an instance of the interface (e.g.,
+          javax.sql.XADataSource) rather than as an instance of the implementation class (e.g.,
+          com.mydb.myXADataSource), the application is not tied at build-time to only use a specific implementation.
+        </para>
+        <para>
+          For the TransactionalDriver class to use a JNDI-registered XADataSource, you need 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 tutorial available at the Java web site.<!--Link?--> 
+        </para>
+        <example>
+          <title>Storing a datasource in a JNDI implementation</title>
+          <programlisting language="Java" role="JAVA"><xi:include href="extras/storing_datasource_in_jndi.java" xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" /> </programlisting>
+          <para>
+            The Context.INITIAL_CONTEXT_FACTORY property is the JNDI way of specifying the type of JNDI
+            implementation to use.
+          </para>
+          <para>
+            The application must pass an appropriate connection URL to the JDBC driver:
+          </para>
+          <programlisting language="Java" role="JAVA">
+          <xi:include href="extras/passing_connection_url_to_jdbc.java" xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" /></programlisting>
+          <para>
+            The JNDI URL must be pre-pended with <literal>jdbc:arjuna:</literal> in order for the TransactionalDriver to
+            recognise that the DataSource must participate within transactions and be driven accordingly.
+          </para>
+        </example>
+      </section>
+      <section>
+        <title>Dynamic class instantiation</title>
+        <para>
+          If a JNDI implementation is not available. you can specify an implementation of the
+          <interfacename>DynamicClass</interfacename> interface, which is used to get the XADataSource object. This is
+          not recommended, but provides a fallback for environments where use of JNDI is not feasible.
+        </para>
+        <para>
+          Use the property <varname>TransactionalDriver.dynamicClass</varname> to specify the implementation to use. An
+          example is <literal>PropertyFileDynamicClass</literal>, a DynamicClass implementation that reads the
+          XADataSource implementation class name and configuration properties from a file, then instantiates and
+          configures it.
+        </para>
+        <note>
+          <title>Deprecated class</title>
+          <para>
+            The oracle_8_1_6 dynamic class is deprecated and should not be used.
+          </para>
+        </note>
+        <example>
+          <title>Instantiating a dynamic class</title>
+          <para>
+            The application code must specify which dynamic class the TransactionalDriver should instantiate when
+            setting up the connection:
+        </para>
+        <programlisting language="Java" role="JAVA"><xi:include href="extras/instantiating_dynamic_class.java" xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" /></programlisting>
+        </example>
+      </section>
+    </section>
+    <section>
+      <title>Using the connection</title>
+      <para>
+        Once the connection is established, all operations on the connection are monitored by JBossJTA. you do not need
+        to use the transactional connection within transactions. If a transaction is not present when the connection is
+        used, then operations are performed directly on the database.
+      </para>
+      <important>
+        <para>
+          JDBC does not support subtransactions.
+        </para>
+      </important>
+      <para>
+        You can use transaction timeouts to automatically terminate transactions if a connection is not terminated
+        within an appropriate period.
+      </para>
+      <para>
+        You can use JBossJTA connections within multiple transactions simultaneously. An example would be different
+        threads, with different notions of the current transaction. JBossJTA does connection pooling for each
+        transaction within the JDBC connection. Although multiple threads may use the same instance of the JDBC
+        connection, internally there may be a separate connection for each transaction. With the exception of method
+        <methodname>close</methodname>, all operations performed on the connection at the application level are only
+        performed on this transaction-specific connection.
+      </para>
+      <para>
+        JBossJTA automatically registers the JDBC driver connection with the transaction via an appropriate
+        resource. When the transaction terminates, this resource either commits or rolls back any changes made to the
+        underlying database via appropriate calls on the JDBC driver.
+      </para>
+      <para>
+        Once created, the driver and any connection can be used in the same way as any other JDBC driver or connection.
+      </para>
+      <example>
+        <title>Creating and using a connection</title>
+        <programlisting language="Java" role="JAVA"><xi:include href="extras/creating_and_using_a_connection.java"
+        xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" /></programlisting>
+      </example>
+    </section>
+    
+    <section>
+      <title>Connection pooling</title>
+      <para>
+        For each user name and password, JBossJTA maintains a single instance of each connection for as long as that
+        connection is in use. Subsequent requests for the same connection get a reference to the original connection,
+        rather than a new instance. Yuo can try to close the connection, but the connection will only actually be closed
+        when all users (including transactions) have either finished with the connection, or issued
+        <methodname>close</methodname> calls.
+      </para>
+    </section>
+    
+    <section>
+      <title>Reusing connections</title>
+      <para>
+        Some JDBC drivers allow the reuse of a connection for multiple different transactions once a given transaction
+        completes. Unfortunately this is not a common feature, and other drivers require a new connection to be
+        obtained for each new transaction. By default, the JBossJTA transactional driver always obtains a new
+        connection for each new transaction. However, if an existing connection is available and is currently unused,
+        JBossJTA can reuse this connection. To turn on this feature, add option <varname>reuseconnection=true</varname>
+        to the JDBC URL. For instance, <code>jdbc:arjuna:sequelink://host:port;databaseName=foo;reuseconnection=true</code>
+      </para>
+    </section>
+    
+    <section>
+      <title>Terminating the transaction</title>
+      <para>
+        When a transaction with an associated JDBC connection terminates, because of the application or because a
+        transaction timeout expires, JBossJTA uses the JDBC driver to drive the database to either commit or roll back
+        any changes made to it. This happens transparently to the application.
+      </para>
+    </section>
+    
+    <section>
+      <title>AutoCommit</title>
+      <para>
+        If property <varname>AutoCommit</varname> of the interface <varname>java.sql.Connection</varname> is set to
+        <literal>true</literal> for JDBC, the execution of every SQL statement is a separate top-level transaction, and
+        it is not possible to group multiple statements to be managed within a single OTS transaction. Therefore,
+        JBossJTA disables <varname>AutoCommit</varname> on JDBC connections before they can be used. If
+        <varname>AutoCommit</varname> is later set to <literal>true</literal> by the application, JBossJTA throws the
+        <systemitem>java.sql.SQLException</systemitem>.
+      </para>
+    </section>
+    
+    <section>
+      <title>Setting isolation levels</title>
+      <para>
+        When you use the JBossJTA JDBC driver, you may need to set the underlying transaction isolation level on the XA
+        connection. By default, this is set to <literal>TRANSACTION_SERIALIZABLE</literal>, but another value may be
+        more appropriate for your application. To change it, set the property
+        <varname>com.arjuna.ats.jdbc.isolationLevel</varname> to the appropriate isolation level in string form. Example
+        values are <literal>TRANSACTION_READ_COMMITTED</literal> or <literal>TRANSACTION_REPEATABLE_READ</literal>.
+      </para>
+      <note>
+        <para>
+          Currently, this property applies to all XA connections created in the JVM.
+        </para>
+      </note>
+    </section>
+  </section>
 </chapter>
 

Modified: labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/Using_JBossTA_In_Application_Servers.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/Using_JBossTA_In_Application_Servers.xml	2010-11-10 04:42:27 UTC (rev 35929)
+++ labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/Using_JBossTA_In_Application_Servers.xml	2010-11-10 06:52:56 UTC (rev 35930)
@@ -4,6 +4,83 @@
 %BOOK_ENTITIES;
 ]>
 <chapter>
-  <title></title>
+  <title>Using JBossJTA in application servers</title>
+  <para>
+    JBoss Application Server is discussed here. Refer to the documentation for your application server for differences.
+  </para>
+  <section>
+    <title>Configuration</title>
+    <para>
+      When JBossJTA runs embedded in JBossAS, the transaction system is configured primarily through the
+      <filename>transaction-jboss-beans.xml</filename> deployment descriptor, which overrides properties read from the
+      default properties file embedded in the .<filename>jar</filename> file.
+    </para>
+    <table>
+      <title>Common configuration attributes</title>
+      <tgroup cols="2">
+        <tbody>
+          <row>
+            <entry>CoordinatorEnvironmentBean.defaultTimeout</entry>
+            <entry>
+              <para>
+                The default transaction timeout to be used for new transactions.  Specified as an integer in seconds.
+              </para>
+            </entry>
+          </row>
+          <row>
+            <entry>CoordinatorEnvironmentBean.enableStatistics</entry>
+            <entry>
+              <para>
+                This determines whether or not the transaction service should gather statistical information.  This
+                information can then be viewed using the TransactionStatistics MBean.  Specified as a Boolean. The
+                default is to not gather this information.
+              </para>
+            </entry>
+          </row>
+        </tbody>
+      </tgroup>
+    </table>
+    <para>
+      See the <filename>transaction-jboss-beans.xml</filename> file and the JBoss Application Server administration and
+      configuration guide for further information.
+    </para>
+  </section>
+  
+  <section>
+    <title>Logging</title>
+    <para>
+      To make JBossTS logging semantically consistent with JBossAS, the
+      <interfacename>TransactionManagerService</interfacename> modifies the level of some log messages, by overriding
+      the value of the <varname>LoggingEnvironmentBean.loggingFactory</varname> property in the
+      <filename>jbossts-properties.xml</filename> file. Therefore, the value of this property has no effect on the
+      logging behavior when running embedded in JBossAS. By forcing use of the <systemitem>log4j_releveler</systemitem>
+      logger, the <interfacename>TransactionManagerService</interfacename> changes the level of all
+      <literal>INFO</literal> level messages in the transaction code to <literal>DEBUG</literal>.  Therefore, these
+      messages do not appear in log files if the filter level is <literal>INFO</literal>. All other log messages behave
+      as normal.
+    </para>
+  </section>
+  
+  <section>
+    <title>The services</title>
+    <para>
+      The <interfacename>TransactionManager</interfacename> bean provides transaction management services to other
+      components in JBossAS. There are two different version of this bean and they requires different configuation. Take
+      care to select the <filename>transaction-jboss-beans.xml</filename> suitable for your needs (local JTA or JTS).
+    </para>
+  </section>
+  
+  <section>
+    <title>Ensuring transactional context is propatated to the server</title>
+    <para>
+      You can coordinate transactions from a coordinator which is not located within the JBoss server
+      , such as when using transactions created by an external OTS server.  To ensure the transaction context is propagated via
+      JRMP invocations to the server, the transaction propagation context factory needs to be explicitly set for the
+      JRMP invoker proxy.  This is done as follows:
+    </para>
+    <programlisting language="Java" role="JAVA"><xi:include href="extras/jrmp_invoker_proxy.java" xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" /></programlisting>
+  </section>
+
+
 </chapter>
 

Added: labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/class.forName.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/class.forName.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/class.forName.java	2010-11-10 06:52:56 UTC (rev 35930)
@@ -0,0 +1,3 @@
+sun.jdbc.odbc.JdbcOdbcDriver drv = new sun.jdbc.odbc.JdbcOdbcDriver();
+
+DriverManager.registerDriver(drv);

Added: labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/creating_and_using_a_connection.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/creating_and_using_a_connection.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/creating_and_using_a_connection.java	2010-11-10 06:52:56 UTC (rev 35930)
@@ -0,0 +1,14 @@
+Statement stmt = conn.createStatement();
+
+try
+    {
+        stmt.executeUpdate("CREATE TABLE test_table (a INTEGER,b INTEGER)");
+    }
+catch (SQLException e)
+    {
+        // table already exists
+    }
+
+stmt.executeUpdate("INSERT INTO test_table (a, b) VALUES (1,2)");
+
+ResultSet res1 = stmt.executeQuery("SELECT * FROM test_table");        

Added: labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/failure_recovery_example.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/failure_recovery_example.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/failure_recovery_example.java	2010-11-10 06:52:56 UTC (rev 35930)
@@ -0,0 +1,167 @@
+/*
+ * Some XAResourceRecovery implementations will do their startup work here,
+ * and then do little or nothing in setDetails. Since this one needs to know
+ * dynamic class name, the constructor does nothing.
+ */
+
+public BasicXARecovery () throws SQLException
+{
+    numberOfConnections = 1;
+    connectionIndex = 0;
+    props = null;
+}
+
+/**
+ * The recovery module will have chopped off this class name already. The
+ * parameter should specify a property file from which the url, user name,
+ * password, etc. can be read.
+ * 
+ * @message com.arjuna.ats.internal.jdbc.recovery.initexp An exception
+ *          occurred during initialisation.
+ */
+
+public boolean initialise (String parameter) throws SQLException
+{
+    if (parameter == null) 
+        return true;
+
+    int breakPosition = parameter.indexOf(BREAKCHARACTER);
+    String fileName = parameter;
+
+    if (breakPosition != -1)
+        {
+            fileName = parameter.substring(0, breakPosition - 1);
+
+            try
+                {
+                    numberOfConnections = Integer.parseInt(parameter
+                                                           .substring(breakPosition + 1));
+                }
+            catch (NumberFormatException e)
+                {
+                    return false;
+                }
+        }
+
+    try
+        {
+            String uri = com.arjuna.common.util.FileLocator
+                .locateFile(fileName);
+            jdbcPropertyManager.propertyManager.load(XMLFilePlugin.class
+                                                     .getName(), uri);
+
+            props = jdbcPropertyManager.propertyManager.getProperties();
+        }
+    catch (Exception e)
+        {
+            return false;
+        }
+
+    return true;
+}
+
+/**
+ * @message com.arjuna.ats.internal.jdbc.recovery.xarec {0} could not find
+ *          information for connection!
+ */
+
+public synchronized XAResource getXAResource () throws SQLException
+{
+    JDBC2RecoveryConnection conn = null;
+
+    if (hasMoreResources())
+        {
+            connectionIndex++;
+
+            conn = getStandardConnection();
+
+            if (conn == null) conn = getJNDIConnection();
+        }
+
+    return conn.recoveryConnection().getConnection().getXAResource();
+}
+
+public synchronized boolean hasMoreResources ()
+{
+    if (connectionIndex == numberOfConnections) 
+        return false;
+    else
+        return true;
+}
+
+private final JDBC2RecoveryConnection getStandardConnection ()
+    throws SQLException
+{
+    String number = new String("" + connectionIndex);
+    String url = new String(dbTag + number + urlTag);
+    String password = new String(dbTag + number + passwordTag);
+    String user = new String(dbTag + number + userTag);
+    String dynamicClass = new String(dbTag + number + dynamicClassTag);
+
+    Properties dbProperties = new Properties();
+
+    String theUser = props.getProperty(user);
+    String thePassword = props.getProperty(password);
+
+    if (theUser != null)
+        {
+            dbProperties.put(TransactionalDriver.userName, theUser);
+            dbProperties.put(TransactionalDriver.password, thePassword);
+
+            String dc = props.getProperty(dynamicClass);
+
+            if (dc != null)
+                dbProperties.put(TransactionalDriver.dynamicClass, dc);
+
+            return new JDBC2RecoveryConnection(url, dbProperties);
+        }
+    else
+        return null;
+}
+
+private final JDBC2RecoveryConnection getJNDIConnection ()
+    throws SQLException
+{
+    String number = new String("" + connectionIndex);
+    String url = new String(dbTag + jndiTag + number + urlTag);
+    String password = new String(dbTag + jndiTag + number + passwordTag);
+    String user = new String(dbTag + jndiTag + number + userTag);
+
+    Properties dbProperties = new Properties();
+
+    String theUser = props.getProperty(user);
+    String thePassword = props.getProperty(password);
+
+    if (theUser != null)
+        {
+            dbProperties.put(TransactionalDriver.userName, theUser);
+            dbProperties.put(TransactionalDriver.password, thePassword);
+
+            return new JDBC2RecoveryConnection(url, dbProperties);
+        }
+    else
+        return null;
+}
+
+private int numberOfConnections;
+private int connectionIndex;
+private Properties props;
+private static final String dbTag = "DB_";
+private static final String urlTag = "_DatabaseURL";
+private static final String passwordTag = "_DatabasePassword";
+private static final String userTag = "_DatabaseUser";
+private static final String dynamicClassTag = "_DatabaseDynamicClass";
+private static final String jndiTag = "JNDI_";
+
+/*
+ * Example:
+ * 
+ * DB2_DatabaseURL=jdbc\:arjuna\:sequelink\://qa02\:20001
+ * DB2_DatabaseUser=tester2 DB2_DatabasePassword=tester
+ * DB2_DatabaseDynamicClass=com.arjuna.ats.internal.jdbc.drivers.sequelink_5_1
+ * 
+ * DB_JNDI_DatabaseURL=jdbc\:arjuna\:jndi DB_JNDI_DatabaseUser=tester1
+ * DB_JNDI_DatabasePassword=tester DB_JNDI_DatabaseName=empay
+ * DB_JNDI_Host=qa02 DB_JNDI_Port=20000
+ */
+private static final char BREAKCHARACTER = ';'; // delimiter for parameters
\ No newline at end of file

Added: labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/instantiating_dynamic_class.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/instantiating_dynamic_class.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/instantiating_dynamic_class.java	2010-11-10 06:52:56 UTC (rev 35930)
@@ -0,0 +1,9 @@
+Properties dbProps = new Properties();
+
+dbProps.setProperty(TransactionalDriver.userName, "user");
+dbProps.setProperty(TransactionalDriver.password, "password");
+dbProps.setProperty(TransactionalDriver.dynamicClass,
+                    "com.arjuna.ats.internal.jdbc.drivers.PropertyFileDynamicClass");
+
+TransactionalDriver arjunaJDBC2Driver = new TransactionalDriver();
+Connection connection = arjunaJDBC2Driver.connect("jdbc:arjuna:/path/to/property/file", dbProperties);

Added: labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/instantiating_transactional_driver.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/instantiating_transactional_driver.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/instantiating_transactional_driver.java	2010-11-10 06:52:56 UTC (rev 35930)
@@ -0,0 +1 @@
+TransactionalDriver arjunaJDBC2Driver = new TransactionalDriver(); 
\ No newline at end of file

Added: labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/jdbc_example.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/jdbc_example.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/jdbc_example.java	2010-11-10 06:52:56 UTC (rev 35930)
@@ -0,0 +1,120 @@
+public class JDBCTest
+{
+    public static void main (String[] args)
+    {
+        /*
+         */
+
+        Connection conn = null;
+        Connection conn2 = null;
+        Statement stmt = null;        // non-tx statement
+        Statement stmtx = null;  // will be a tx-statement
+        Properties dbProperties = new Properties();
+
+        try
+            {
+                System.out.println("\nCreating connection to database: "+url);
+
+                /*
+                 * Create conn and conn2 so that they are bound to the JBossTS
+                 * transactional JDBC driver. The details of how to do this will
+                 * depend on your environment, the database you wish to use and
+                 * whether or not you want to use the Direct or JNDI approach. See
+                 * the appropriate chapter in the JTA Programmers Guide.
+                 */
+
+                stmt = conn.createStatement();  // non-tx statement
+
+                try
+                    {
+                        stmt.executeUpdate("DROP TABLE test_table");
+                        stmt.executeUpdate("DROP TABLE test_table2");
+                    }
+                catch (Exception e)
+                    {
+                        // assume not in database.
+                    }
+
+                try
+                    {
+                        stmt.executeUpdate("CREATE TABLE test_table (a INTEGER,b INTEGER)");
+                        stmt.executeUpdate("CREATE TABLE test_table2 (a INTEGER,b INTEGER)");
+                    }
+                catch (Exception e)
+                    {
+                    }
+
+                try
+                    {
+                        System.out.println("Starting top-level transaction.");
+
+                        com.arjuna.ats.jta.UserTransaction.userTransaction().begin();
+
+                        stmtx = conn.createStatement(); // will be a tx-statement
+
+                        System.out.println("\nAdding entries to table 1.");
+
+                        stmtx.executeUpdate("INSERT INTO test_table (a, b) VALUES (1,2)");
+
+                        ResultSet res1 = null;
+
+                        System.out.println("\nInspecting table 1.");
+
+                        res1 = stmtx.executeQuery("SELECT * FROM test_table");
+                        while (res1.next())
+                            {
+                                System.out.println("Column 1: "+res1.getInt(1));
+                                System.out.println("Column 2: "+res1.getInt(2));
+                            }
+
+                        System.out.println("\nAdding entries to table 2.");
+
+                        stmtx.executeUpdate("INSERT INTO test_table2 (a, b) VALUES (3,4)");
+                        res1 = stmtx.executeQuery("SELECT * FROM test_table2");
+                        System.out.println("\nInspecting table 2.");
+
+                        while (res1.next())
+                            {
+                                System.out.println("Column 1: "+res1.getInt(1));
+                                System.out.println("Column 2: "+res1.getInt(2));
+                            }
+                        System.out.print("\nNow attempting to rollback changes.");
+                        com.arjuna.ats.jta.UserTransaction.userTransaction().rollback();
+
+                        com.arjuna.ats.jta.UserTransaction.userTransaction().begin();
+                        stmtx = conn.createStatement();
+                        ResultSet res2 = null;
+
+                        System.out.println("\nNow checking state of table 1.");
+
+                        res2 = stmtx.executeQuery("SELECT * FROM test_table");
+                        while (res2.next())
+                            {
+                                System.out.println("Column 1: "+res2.getInt(1));
+                                System.out.println("Column 2: "+res2.getInt(2));
+                            }
+
+                        System.out.println("\nNow checking state of table 2.");
+
+                        stmtx = conn.createStatement();
+                        res2 = stmtx.executeQuery("SELECT * FROM test_table2");
+                        while (res2.next())
+                            {
+                                System.out.println("Column 1: "+res2.getInt(1));
+                                System.out.println("Column 2: "+res2.getInt(2));
+                            }
+
+                        com.arjuna.ats.jta.UserTransaction.userTransaction().commit(true);
+                    }
+                catch (Exception ex)
+                    {
+                        ex.printStackTrace();
+                        System.exit(0);
+                    }
+            }
+        catch (Exception sysEx)
+            {
+                sysEx.printStackTrace();
+                System.exit(0);
+            }
+    }
\ No newline at end of file

Added: labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/jrmp_invoker_proxy.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/jrmp_invoker_proxy.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/jrmp_invoker_proxy.java	2010-11-10 06:52:56 UTC (rev 35930)
@@ -0,0 +1 @@
+JRMPInvokerProxy.setTPCFactory( new com.arjuna.ats.internal.jbossatx.jts.PropagationContextManager() );
\ No newline at end of file

Added: labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/passing_connection_url_to_jdbc.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/passing_connection_url_to_jdbc.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/passing_connection_url_to_jdbc.java	2010-11-10 06:52:56 UTC (rev 35930)
@@ -0,0 +1,13 @@
+Properties dbProps = new Properties();
+
+dbProps.setProperty(TransactionalDriver.userName, "user");
+dbProps.setProperty(TransactionalDriver.password, "password");
+
+// the driver uses its own JNDI context info, remember to set it up:
+jdbcPropertyManager.propertyManager.setProperty(
+                                                "Context.INITIAL_CONTEXT_FACTORY", initialCtx);
+jdbcPropertyManager.propertyManager.setProperty(
+                                                "Context.PROVIDER_URL", myUrl);
+
+TransactionalDriver arjunaJDBCDriver = new TransactionalDriver();
+Connection connection = arjunaJDBCDriver.connect("jdbc:arjuna:jdbc/foo", dbProps);

Added: labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/registering_transactionaldriver_using_jdbc_driver_manager.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/registering_transactionaldriver_using_jdbc_driver_manager.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/registering_transactionaldriver_using_jdbc_driver_manager.java	2010-11-10 06:52:56 UTC (rev 35930)
@@ -0,0 +1,13 @@
+Properties p = System.getProperties(); 
+
+switch (dbType)
+{
+case MYSQL:
+    p.put("jdbc.drivers", "com.mysql.jdbc.Driver"); 
+    break;
+case PGSQL:
+    p.put("jdbc.drivers", "org.postgresql.Driver"); 
+    break;
+}
+
+System.setProperties(p);

Added: labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/storing_datasource_in_jndi.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/storing_datasource_in_jndi.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Development_Guide/en-US/extras/storing_datasource_in_jndi.java	2010-11-10 06:52:56 UTC (rev 35930)
@@ -0,0 +1,9 @@
+XADataSource ds = MyXADataSource();
+Hashtable env = new Hashtable();
+String initialCtx = PropertyManager.getProperty("Context.INITIAL_CONTEXT_FACTORY");
+
+env.put(Context.INITIAL_CONTEXT_FACTORY, initialCtx);
+
+initialContext ctx = new InitialContext(env);
+
+ctx.bind("jdbc/foo", ds);



More information about the jboss-svn-commits mailing list