1191 lines
51 KiB
XML
1191 lines
51 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
|
|
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
|
|
<chapter id="cci">
|
|
<title>JCA CCI</title>
|
|
|
|
<section id="cci-introduction">
|
|
<title>Introduction</title>
|
|
|
|
<para>Java EE provides a specification to standardize access to enterprise
|
|
information systems (EIS): the JCA (J2EE Connector Architecture). This
|
|
specification is divided into several different parts:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>SPI (Service provider interfaces) that the connector provider
|
|
must implement. These interfaces constitute a resource adapter which
|
|
can be deployed on a Java EE application server. In such a scenario, the
|
|
server manages connection pooling, transaction and security (managed
|
|
mode). The application server is also responsible for managing the
|
|
configuration, which is held outside the client application. A
|
|
connector can be used without an application server as well; in this
|
|
case, the application must configure it directly (non-managed
|
|
mode).</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>CCI (Common Client Interface) that an application can use to
|
|
interact with the connector and thus communicate with an EIS. An API
|
|
for local transaction demarcation is provided as well.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>The aim of the Spring CCI support is to provide classes to access a
|
|
CCI connector in typical Spring style, leveraging the Spring Framework's
|
|
general resource and transaction management facilities.</para>
|
|
|
|
<note>
|
|
<para>The client side of connectors doesn't alway use CCI. Some
|
|
connectors expose their own APIs, only providing JCA resource adapter to
|
|
use the system contracts of a Java EE container (connection pooling, global
|
|
transactions, security). Spring does not offer special support for such
|
|
connector-specific APIs.</para>
|
|
</note>
|
|
</section>
|
|
|
|
<section id="cci-config">
|
|
<title>Configuring CCI</title>
|
|
|
|
<section id="cci-config-connector">
|
|
<title>Connector configuration</title>
|
|
|
|
<para>The base resource to use JCA CCI is the
|
|
<interfacename>ConnectionFactory</interfacename> interface. The
|
|
connector used must provide an implementation of this interface.</para>
|
|
|
|
<para>To use your connector, you can deploy it on your application
|
|
server and fetch the <interfacename>ConnectionFactory</interfacename>
|
|
from the server's JNDI environment (managed mode). The connector must be
|
|
packaged as a RAR file (resource adapter archive) and contain a
|
|
<filename>ra.xml</filename> file to describe its deployment
|
|
characteristics. The actual name of the resource is specified when you
|
|
deploy it. To access it within Spring, simply use Spring's
|
|
<classname>JndiObjectFactoryBean</classname> /
|
|
<literal><jee:jndi-lookup></literal> fetch the factory by its JNDI
|
|
name.</para>
|
|
|
|
<para>Another way to use a connector is to embed it in your application
|
|
(non-managed mode), not using an application server to deploy and
|
|
configure it. Spring offers the possibility to configure a connector as
|
|
a bean, through a provided <literal>FactoryBean</literal>
|
|
(<classname>LocalConnectionFactoryBean</classname>). In this manner, you
|
|
only need the connector library in the classpath (no RAR file and no
|
|
<filename>ra.xml</filename> descriptor needed). The library must be
|
|
extracted from the connector's RAR file, if necessary.</para>
|
|
|
|
<para>Once you have got access to your
|
|
<interfacename>ConnectionFactory</interfacename> instance, you can
|
|
inject it into your components. These components can either be coded
|
|
against the plain CCI API or leverage Spring's support classes for CCI
|
|
access (e.g. <classname>CciTemplate</classname>).</para>
|
|
|
|
<note>
|
|
<para>When you use a connector in non-managed mode, you can't use
|
|
global transactions because the resource is never enlisted / delisted
|
|
in the current global transaction of the current thread. The resource
|
|
is simply not aware of any global Java EE transactions that might be
|
|
running.</para>
|
|
</note>
|
|
</section>
|
|
|
|
<section id="cci-config-connectionfactory">
|
|
<title><interfacename>ConnectionFactory</interfacename> configuration in
|
|
Spring</title>
|
|
|
|
<para>In order to make connections to the EIS, you need to obtain a
|
|
<interfacename>ConnectionFactory</interfacename> from the application
|
|
server if you are in a managed mode, or directly from Spring if you are
|
|
in a non-managed mode.</para>
|
|
|
|
<para>In a managed mode, you access a
|
|
<interfacename>ConnectionFactory</interfacename> from JNDI; its
|
|
properties will be configured in the application server.</para>
|
|
|
|
<programlisting language="xml"><jee:jndi-lookup id="eciConnectionFactory" jndi-name="eis/cicseci"/></programlisting>
|
|
|
|
<para>In non-managed mode, you must configure the
|
|
<interfacename>ConnectionFactory</interfacename> you want to use in the
|
|
configuration of Spring as a JavaBean. The
|
|
<classname>LocalConnectionFactoryBean</classname> class offers this
|
|
setup style, passing in the
|
|
<classname>ManagedConnectionFactory</classname> implementation of your
|
|
connector, exposing the application-level CCI
|
|
<interfacename>ConnectionFactory</interfacename>.</para>
|
|
|
|
<programlisting language="xml"><bean id="eciManagedConnectionFactory" class="com.ibm.connector2.cics.ECIManagedConnectionFactory">
|
|
<property name="serverName" value="TXSERIES"/>
|
|
<property name="connectionURL" value="tcp://localhost/"/>
|
|
<property name="portNumber" value="2006"/>
|
|
</bean>
|
|
|
|
<bean id="eciConnectionFactory" class="org.springframework.jca.support.LocalConnectionFactoryBean">
|
|
<property name="managedConnectionFactory" ref="eciManagedConnectionFactory"/>
|
|
</bean></programlisting>
|
|
|
|
<note>
|
|
<para>You can't directly instantiate a specific
|
|
<interfacename>ConnectionFactory</interfacename>. You need to go
|
|
through the corresponding implementation of the
|
|
<classname>ManagedConnectionFactory</classname> interface for your
|
|
connector. This interface is part of the JCA SPI specification.</para>
|
|
</note>
|
|
</section>
|
|
|
|
<section id="cci-config-cci-connections">
|
|
<title>Configuring CCI connections</title>
|
|
|
|
<para>JCA CCI allow the developer to configure the connections to the
|
|
EIS using the <interfacename>ConnectionSpec</interfacename>
|
|
implementation of your connector. In order to configure its properties,
|
|
you need to wrap the target connection factory with a dedicated adapter,
|
|
<classname>ConnectionSpecConnectionFactoryAdapter</classname>. So, the
|
|
dedicated <interfacename>ConnectionSpec</interfacename> can be
|
|
configured with the property <literal>connectionSpec</literal> (as an
|
|
inner bean).</para>
|
|
|
|
<para>This property is not mandatory because the CCI
|
|
<interfacename>ConnectionFactory</interfacename> interface defines two
|
|
different methods to obtain a CCI connection. Some of the
|
|
<interfacename>ConnectionSpec</interfacename> properties can often be
|
|
configured in the application server (in managed mode) or on the
|
|
corresponding local <classname>ManagedConnectionFactory</classname>
|
|
implementation.</para>
|
|
|
|
<programlisting language="java">public interface ConnectionFactory implements Serializable, Referenceable {
|
|
...
|
|
Connection getConnection() throws ResourceException;
|
|
Connection getConnection(ConnectionSpec connectionSpec) throws ResourceException;
|
|
...
|
|
}</programlisting>
|
|
|
|
<para>Spring provides a
|
|
<classname>ConnectionSpecConnectionFactoryAdapter</classname> that
|
|
allows for specifying a <interfacename>ConnectionSpec</interfacename>
|
|
instance to use for all operations on a given factory. If the adapter's
|
|
<literal>connectionSpec</literal> property is specified, the adapter
|
|
uses the <literal>getConnection</literal> variant without argument, else
|
|
the one with the <interfacename>ConnectionSpec</interfacename>
|
|
argument.</para>
|
|
|
|
<programlisting language="xml"><bean id="managedConnectionFactory"
|
|
class="com.sun.connector.cciblackbox.CciLocalTxManagedConnectionFactory">
|
|
<property name="connectionURL" value="jdbc:hsqldb:hsql://localhost:9001"/>
|
|
<property name="driverName" value="org.hsqldb.jdbcDriver"/>
|
|
</bean>
|
|
|
|
<bean id="targetConnectionFactory"
|
|
class="org.springframework.jca.support.LocalConnectionFactoryBean">
|
|
<property name="managedConnectionFactory" ref="managedConnectionFactory"/>
|
|
</bean>
|
|
|
|
<bean id="connectionFactory"
|
|
class="org.springframework.jca.cci.connection.ConnectionSpecConnectionFactoryAdapter">
|
|
<property name="targetConnectionFactory" ref="targetConnectionFactory"/>
|
|
<property name="connectionSpec">
|
|
<bean class="com.sun.connector.cciblackbox.CciConnectionSpec">
|
|
<property name="user" value="sa"/>
|
|
<property name="password" value=""/>
|
|
</bean>
|
|
</property>
|
|
</bean></programlisting>
|
|
</section>
|
|
|
|
<section id="cci-config-single-connection">
|
|
<title>Using a single CCI connection</title>
|
|
|
|
<para>If you want to use a single CCI connection, Spring provides a
|
|
further <interfacename>ConnectionFactory</interfacename> adapter to
|
|
manage this. The <classname>SingleConnectionFactory</classname> adapter
|
|
class will open a single connection lazily and close it when this bean
|
|
is destroyed at application shutdown. This class will expose special
|
|
<interfacename>Connection</interfacename> proxies that behave
|
|
accordingly, all sharing the same underlying physical connection.</para>
|
|
|
|
<programlisting language="xml"><bean id="eciManagedConnectionFactory"
|
|
class="com.ibm.connector2.cics.ECIManagedConnectionFactory">
|
|
<property name="serverName" value="TEST"/>
|
|
<property name="connectionURL" value="tcp://localhost/"/>
|
|
<property name="portNumber" value="2006"/>
|
|
</bean>
|
|
|
|
<bean id="targetEciConnectionFactory"
|
|
class="org.springframework.jca.support.LocalConnectionFactoryBean">
|
|
<property name="managedConnectionFactory" ref="eciManagedConnectionFactory"/>
|
|
</bean>
|
|
|
|
<bean id="eciConnectionFactory"
|
|
class="org.springframework.jca.cci.connection.SingleConnectionFactory">
|
|
<property name="targetConnectionFactory" ref="targetEciConnectionFactory"/>
|
|
</bean></programlisting>
|
|
|
|
<note>
|
|
<para>This <interfacename>ConnectionFactory</interfacename> adapter
|
|
cannot directly be configured with a
|
|
<interfacename>ConnectionSpec</interfacename>. Use an intermediary
|
|
<classname>ConnectionSpecConnectionFactoryAdapter</classname> that the
|
|
<classname>SingleConnectionFactory</classname> talks to if you require
|
|
a single connection for a specific
|
|
<interfacename>ConnectionSpec</interfacename>.</para>
|
|
</note>
|
|
</section>
|
|
</section>
|
|
|
|
<section id="cci-using">
|
|
<title>Using Spring's CCI access support</title>
|
|
|
|
<section id="cci-record-creator">
|
|
<title>Record conversion</title>
|
|
|
|
<para>One of the aims of the JCA CCI support is to provide convenient
|
|
facilities for manipulating CCI records. The developer can specify the
|
|
strategy to create records and extract datas from records, for use with
|
|
Spring's <classname>CciTemplate</classname>. The following interfaces
|
|
will configure the strategy to use input and output records if you don't
|
|
want to work with records directly in your application.</para>
|
|
|
|
<para>In order to create an input <interfacename>Record</interfacename>,
|
|
the developer can use a dedicated implementation of the
|
|
<interfacename>RecordCreator</interfacename> interface.</para>
|
|
|
|
<programlisting language="java">public interface RecordCreator {
|
|
|
|
Record createRecord(RecordFactory recordFactory) throws ResourceException, DataAccessException;
|
|
}</programlisting>
|
|
|
|
<para>As you can see, the <literal>createRecord(..)</literal> method
|
|
receives a <interfacename>RecordFactory</interfacename> instance as
|
|
parameter, which corresponds to the
|
|
<interfacename>RecordFactory</interfacename> of the
|
|
<interfacename>ConnectionFactory</interfacename> used. This reference
|
|
can be used to create <interfacename>IndexedRecord</interfacename> or
|
|
<interfacename>MappedRecord</interfacename> instances. The following
|
|
sample shows how to use the <interfacename>RecordCreator</interfacename>
|
|
interface and indexed/mapped records.</para>
|
|
|
|
<programlisting language="java">public class MyRecordCreator implements RecordCreator {
|
|
|
|
public Record createRecord(RecordFactory recordFactory) throws ResourceException {
|
|
IndexedRecord input = recordFactory.createIndexedRecord("input");
|
|
input.add(new Integer(id));
|
|
return input;
|
|
}
|
|
}</programlisting>
|
|
|
|
<para>An output <interfacename>Record</interfacename> can be used to
|
|
receive data back from the EIS. Hence, a specific implementation of the
|
|
<interfacename>RecordExtractor</interfacename> interface can be passed
|
|
to Spring's <classname>CciTemplate</classname> for extracting data from
|
|
the output <interfacename>Record</interfacename>.</para>
|
|
|
|
<programlisting language="java">public interface RecordExtractor {
|
|
|
|
Object extractData(Record record) throws ResourceException, SQLException, DataAccessException;
|
|
}</programlisting>
|
|
|
|
<para>The following sample shows how to use the
|
|
<interfacename>RecordExtractor</interfacename> interface.</para>
|
|
|
|
<programlisting language="java">public class MyRecordExtractor implements RecordExtractor {
|
|
|
|
public Object extractData(Record record) throws ResourceException {
|
|
CommAreaRecord commAreaRecord = (CommAreaRecord) record;
|
|
String str = new String(commAreaRecord.toByteArray());
|
|
String field1 = string.substring(0,6);
|
|
String field2 = string.substring(6,1);
|
|
return new OutputObject(Long.parseLong(field1), field2);
|
|
}
|
|
}</programlisting>
|
|
</section>
|
|
|
|
<section id="cci-using-template">
|
|
<title>The <classname>CciTemplate</classname></title>
|
|
|
|
<para>The <classname>CciTemplate</classname> is the central class of the
|
|
core CCI support package
|
|
(<literal>org.springframework.jca.cci.core</literal>). It simplifies the
|
|
use of CCI since it handles the creation and release of resources. This
|
|
helps to avoid common errors like forgetting to always close the
|
|
connection. It cares for the lifecycle of connection and interaction
|
|
objects, letting application code focus on generating input records from
|
|
application data and extracting application data from output
|
|
records.</para>
|
|
|
|
<para>The JCA CCI specification defines two distinct methods to call
|
|
operations on an EIS. The CCI <interfacename>Interaction</interfacename>
|
|
interface provides two execute method signatures:</para>
|
|
|
|
<programlisting language="java">public interface javax.resource.cci.Interaction {
|
|
...
|
|
boolean execute(InteractionSpec spec, Record input, Record output) throws ResourceException;
|
|
|
|
Record execute(InteractionSpec spec, Record input) throws ResourceException;
|
|
...
|
|
}</programlisting>
|
|
|
|
<para>Depending on the template method called,
|
|
<classname>CciTemplate</classname> will know which
|
|
<literal>execute</literal> method to call on the interaction. In any
|
|
case, a correctly initialized
|
|
<interfacename>InteractionSpec</interfacename> instance is
|
|
mandatory.</para>
|
|
|
|
<para><literal>CciTemplate.execute(..)</literal> can be used in two
|
|
ways:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>With direct <interfacename>Record</interfacename> arguments.
|
|
In this case, you simply need to pass the CCI input record in, and
|
|
the returned object be the corresponding CCI output record.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>With application objects, using record mapping. In this case,
|
|
you need to provide corresponding
|
|
<interfacename>RecordCreator</interfacename> and
|
|
<interfacename>RecordExtractor</interfacename> instances.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>With the first approach, the following methods of the template
|
|
will be used. These methods directly correspond to those on the
|
|
<interfacename>Interaction</interfacename> interface.</para>
|
|
|
|
<programlisting language="java">public class CciTemplate implements CciOperations {
|
|
|
|
public Record execute(InteractionSpec spec, Record inputRecord)
|
|
throws DataAccessException { ... }
|
|
|
|
public void execute(InteractionSpec spec, Record inputRecord, Record outputRecord)
|
|
throws DataAccessException { ... }
|
|
|
|
}</programlisting>
|
|
|
|
<para>With the second approach, we need to specify the record creation
|
|
and record extraction strategies as arguments. The interfaces used are
|
|
those describe in the previous section on record conversion. The
|
|
corresponding <classname>CciTemplate</classname> methods are the
|
|
following:</para>
|
|
|
|
<programlisting language="java">public class CciTemplate implements CciOperations {
|
|
|
|
public Record execute(InteractionSpec spec, RecordCreator inputCreator)
|
|
throws DataAccessException { ... }
|
|
|
|
public Object execute(InteractionSpec spec, Record inputRecord, RecordExtractor outputExtractor)
|
|
throws DataAccessException { ... }
|
|
|
|
public Object execute(InteractionSpec spec, RecordCreator creator, RecordExtractor extractor)
|
|
throws DataAccessException { ... }
|
|
|
|
}</programlisting>
|
|
|
|
<para>Unless the <literal>outputRecordCreator</literal> property is set
|
|
on the template (see the following section), every method will call the
|
|
corresponding <literal>execute</literal> method of the CCI
|
|
<interfacename>Interaction</interfacename> with two parameters:
|
|
<interfacename>InteractionSpec</interfacename> and input
|
|
<interfacename>Record</interfacename>, receiving an output
|
|
<interfacename>Record</interfacename> as return value.</para>
|
|
|
|
<para><classname>CciTemplate</classname> also provides methods to create
|
|
<literal>IndexRecord</literal> and <literal>MappedRecord</literal>
|
|
outside a <interfacename>RecordCreator</interfacename> implementation,
|
|
through its <literal>createIndexRecord(..)</literal> and
|
|
<literal>createMappedRecord(..)</literal> methods. This can be used
|
|
within DAO implementations to create
|
|
<interfacename>Record</interfacename> instances to pass into
|
|
corresponding <literal>CciTemplate.execute(..)</literal> methods.</para>
|
|
|
|
<programlisting language="java">public class CciTemplate implements CciOperations {
|
|
|
|
public IndexedRecord createIndexedRecord(String name) throws DataAccessException { ... }
|
|
|
|
public MappedRecord createMappedRecord(String name) throws DataAccessException { ... }
|
|
|
|
}</programlisting>
|
|
</section>
|
|
|
|
<section id="cci-using-dao">
|
|
<title>DAO support</title>
|
|
|
|
<para>Spring's CCI support provides a abstract class for DAOs,
|
|
supporting injection of a
|
|
<interfacename>ConnectionFactory</interfacename> or a
|
|
<classname>CciTemplate</classname> instances. The name of the class is
|
|
<classname>CciDaoSupport</classname>: It provides simple
|
|
<literal>setConnectionFactory</literal> and
|
|
<literal>setCciTemplate</literal> methods. Internally, this class will
|
|
create a <classname>CciTemplate</classname> instance for a passed-in
|
|
<interfacename>ConnectionFactory</interfacename>, exposing it to
|
|
concrete data access implementations in subclasses.</para>
|
|
|
|
<programlisting language="java">public abstract class CciDaoSupport {
|
|
|
|
public void setConnectionFactory(ConnectionFactory connectionFactory) { ... }
|
|
public ConnectionFactory getConnectionFactory() { ... }
|
|
|
|
public void setCciTemplate(CciTemplate cciTemplate) { ... }
|
|
public CciTemplate getCciTemplate() { ... }
|
|
|
|
}</programlisting>
|
|
</section>
|
|
|
|
<section id="automatic-output-generation">
|
|
<title>Automatic output record generation</title>
|
|
|
|
<para>If the connector used only supports the
|
|
<methodname>Interaction.execute(..)</methodname> method with input and
|
|
output records as parameters (that is, it requires the desired output
|
|
record to be passed in instead of returning an appropriate output
|
|
record), you can set the <literal>outputRecordCreator</literal> property
|
|
of the <classname>CciTemplate</classname> to automatically generate an
|
|
output record to be filled by the JCA connector when the response is
|
|
received. This record will be then returned to the caller of the
|
|
template.</para>
|
|
|
|
<para>This property simply holds an implementation of the
|
|
<interfacename>RecordCreator</interfacename> interface, used for that
|
|
purpose. The <interfacename>RecordCreator</interfacename> interface has
|
|
already been discussed in <xref linkend="cci-record-creator" />. The
|
|
<literal>outputRecordCreator</literal> property must be directly
|
|
specified on the <classname>CciTemplate</classname>. This could be done
|
|
in the application code like so:</para>
|
|
|
|
<programlisting language="java">cciTemplate.setOutputRecordCreator(new EciOutputRecordCreator());</programlisting>
|
|
|
|
<para>Or (recommended) in the Spring configuration, if the
|
|
<classname>CciTemplate</classname> is configured as a dedicated bean
|
|
instance:</para>
|
|
|
|
<programlisting language="xml"><bean id="eciOutputRecordCreator" class="eci.EciOutputRecordCreator"/>
|
|
|
|
<bean id="cciTemplate" class="org.springframework.jca.cci.core.CciTemplate">
|
|
<property name="connectionFactory" ref="eciConnectionFactory"/>
|
|
<property name="outputRecordCreator" ref="eciOutputRecordCreator"/>
|
|
</bean></programlisting>
|
|
|
|
<note>
|
|
<para>As the <classname>CciTemplate</classname> class is thread-safe,
|
|
it will usually be configured as a shared instance.</para>
|
|
</note>
|
|
</section>
|
|
|
|
<section id="template-summary">
|
|
<title>Summary</title>
|
|
|
|
<para>The following table summarizes the mechanisms of the
|
|
<classname>CciTemplate</classname> class and the corresponding methods
|
|
called on the CCI <interfacename>Interaction</interfacename>
|
|
interface:<table frame="all" id="cci-interaction-execute-methods">
|
|
<title>Usage of <interfacename>Interaction</interfacename> execute
|
|
methods</title>
|
|
|
|
<tgroup cols="3">
|
|
<thead>
|
|
<row>
|
|
<entry align="center">CciTemplate method signature</entry>
|
|
|
|
<entry align="center">CciTemplate outputRecordCreator
|
|
property</entry>
|
|
|
|
<entry align="center">execute method called on the CCI
|
|
Interaction</entry>
|
|
</row>
|
|
</thead>
|
|
|
|
<tbody>
|
|
<row>
|
|
<entry align="center">Record execute(InteractionSpec,
|
|
Record)</entry>
|
|
|
|
<entry align="center">not set</entry>
|
|
|
|
<entry align="center">Record execute(InteractionSpec,
|
|
Record)</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry align="center">Record execute(InteractionSpec,
|
|
Record)</entry>
|
|
|
|
<entry align="center">set</entry>
|
|
|
|
<entry align="center">boolean execute(InteractionSpec, Record,
|
|
Record)</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry align="center">void execute(InteractionSpec, Record,
|
|
Record)</entry>
|
|
|
|
<entry align="center">not set</entry>
|
|
|
|
<entry align="center">void execute(InteractionSpec, Record,
|
|
Record)</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry align="center">void execute(InteractionSpec, Record,
|
|
Record)</entry>
|
|
|
|
<entry align="center">set</entry>
|
|
|
|
<entry align="center">void execute(InteractionSpec, Record,
|
|
Record)</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry align="center">Record execute(InteractionSpec,
|
|
RecordCreator)</entry>
|
|
|
|
<entry align="center">not set</entry>
|
|
|
|
<entry align="center">Record execute(InteractionSpec,
|
|
Record)</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry align="center">Record execute(InteractionSpec,
|
|
RecordCreator)</entry>
|
|
|
|
<entry align="center">set</entry>
|
|
|
|
<entry align="center">void execute(InteractionSpec, Record,
|
|
Record)</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry align="center">Record execute(InteractionSpec, Record,
|
|
RecordExtractor)</entry>
|
|
|
|
<entry align="center">not set</entry>
|
|
|
|
<entry align="center">Record execute(InteractionSpec,
|
|
Record)</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry align="center">Record execute(InteractionSpec, Record,
|
|
RecordExtractor)</entry>
|
|
|
|
<entry align="center">set</entry>
|
|
|
|
<entry align="center">void execute(InteractionSpec, Record,
|
|
Record)</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry align="center">Record execute(InteractionSpec,
|
|
RecordCreator, RecordExtractor)</entry>
|
|
|
|
<entry align="center">not set</entry>
|
|
|
|
<entry align="center">Record execute(InteractionSpec,
|
|
Record)</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry align="center">Record execute(InteractionSpec,
|
|
RecordCreator, RecordExtractor)</entry>
|
|
|
|
<entry align="center">set</entry>
|
|
|
|
<entry align="center">void execute(InteractionSpec, Record,
|
|
Record)</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table></para>
|
|
</section>
|
|
|
|
<section id="cci-straight">
|
|
<title>Using a CCI <interfacename>Connection</interfacename> and
|
|
<interfacename>Interaction</interfacename> directly</title>
|
|
|
|
<para><classname>CciTemplate</classname> also offers the possibility to
|
|
work directly with CCI connections and interactions, in the same manner
|
|
as <classname>JdbcTemplate</classname> and
|
|
<classname>JmsTemplate</classname>. This is useful when you want to
|
|
perform multiple operations on a CCI connection or interaction, for
|
|
example.</para>
|
|
|
|
<para>The interface <interfacename>ConnectionCallback</interfacename>
|
|
provides a CCI <interfacename>Connection</interfacename> as argument, in
|
|
order to perform custom operations on it, plus the CCI
|
|
<interfacename>ConnectionFactory</interfacename> which the
|
|
<interfacename>Connection</interfacename> was created with. The latter
|
|
can be useful for example to get an associated
|
|
<interfacename>RecordFactory</interfacename> instance and create
|
|
indexed/mapped records, for example.</para>
|
|
|
|
<programlisting language="java">public interface ConnectionCallback {
|
|
|
|
Object doInConnection(Connection connection, ConnectionFactory connectionFactory)
|
|
throws ResourceException, SQLException, DataAccessException;
|
|
}</programlisting>
|
|
|
|
<para>The interface <interfacename>InteractionCallback</interfacename>
|
|
provides the CCI <interfacename>Interaction</interfacename>, in order to
|
|
perform custom operations on it, plus the corresponding CCI
|
|
<interfacename>ConnectionFactory</interfacename>.</para>
|
|
|
|
<programlisting language="java">public interface InteractionCallback {
|
|
|
|
Object doInInteraction(Interaction interaction, ConnectionFactory connectionFactory)
|
|
throws ResourceException, SQLException, DataAccessException;
|
|
}</programlisting>
|
|
|
|
<note>
|
|
<para><interfacename>InteractionSpec</interfacename> objects can
|
|
either be shared across multiple template calls or newly created
|
|
inside every callback method. This is completely up to the DAO
|
|
implementation.</para>
|
|
</note>
|
|
</section>
|
|
|
|
<section id="cci-template-example">
|
|
<title>Example for <classname>CciTemplate</classname> usage</title>
|
|
|
|
<para>In this section, the usage of the
|
|
<classname>CciTemplate</classname> will be shown to acces to a CICS with
|
|
ECI mode, with the IBM CICS ECI connector.</para>
|
|
|
|
<para>Firstly, some initializations on the CCI
|
|
<interfacename>InteractionSpec</interfacename> must be done to specify
|
|
which CICS program to access and how to interact with it.</para>
|
|
|
|
<programlisting language="java">ECIInteractionSpec interactionSpec = new ECIInteractionSpec();
|
|
interactionSpec.setFunctionName("MYPROG");
|
|
interactionSpec.setInteractionVerb(ECIInteractionSpec.SYNC_SEND_RECEIVE);</programlisting>
|
|
|
|
<para>Then the program can use CCI via Spring's template and specify
|
|
mappings between custom objects and CCI
|
|
<literal>Records</literal>.</para>
|
|
|
|
<programlisting language="java">public class MyDaoImpl extends CciDaoSupport implements MyDao {
|
|
|
|
public OutputObject getData(InputObject input) {
|
|
ECIInteractionSpec interactionSpec = ...;
|
|
|
|
OutputObject output = (ObjectOutput) getCciTemplate().execute(interactionSpec,
|
|
new RecordCreator() {
|
|
public Record createRecord(RecordFactory recordFactory) throws ResourceException {
|
|
return new CommAreaRecord(input.toString().getBytes());
|
|
}
|
|
},
|
|
new RecordExtractor() {
|
|
public Object extractData(Record record) throws ResourceException {
|
|
CommAreaRecord commAreaRecord = (CommAreaRecord)record;
|
|
String str = new String(commAreaRecord.toByteArray());
|
|
String field1 = string.substring(0,6);
|
|
String field2 = string.substring(6,1);
|
|
return new OutputObject(Long.parseLong(field1), field2);
|
|
}
|
|
});
|
|
|
|
return output;
|
|
}
|
|
}</programlisting>
|
|
|
|
<para>As discussed previously, callbacks can be used to work directly on
|
|
CCI connections or interactions.</para>
|
|
|
|
<programlisting language="java">public class MyDaoImpl extends CciDaoSupport implements MyDao {
|
|
|
|
public OutputObject getData(InputObject input) {
|
|
ObjectOutput output = (ObjectOutput) getCciTemplate().execute(
|
|
new ConnectionCallback() {
|
|
public Object doInConnection(Connection connection, ConnectionFactory factory)
|
|
throws ResourceException {
|
|
|
|
<lineannotation>// do something...</lineannotation>
|
|
}
|
|
});
|
|
}
|
|
return output;
|
|
}
|
|
}</programlisting>
|
|
|
|
<note>
|
|
<para>With a <interfacename>ConnectionCallback</interfacename>, the
|
|
<interfacename>Connection</interfacename> used will be managed and
|
|
closed by the <classname>CciTemplate</classname>, but any interactions
|
|
created on the connection must be managed by the callback
|
|
implementation.</para>
|
|
</note>
|
|
|
|
<para>For a more specific callback, you can implement an
|
|
<interfacename>InteractionCallback</interfacename>. The passed-in
|
|
<interfacename>Interaction</interfacename> will be managed and closed by
|
|
the <classname>CciTemplate</classname> in this case.</para>
|
|
|
|
<programlisting language="java">public class MyDaoImpl extends CciDaoSupport implements MyDao {
|
|
|
|
public String getData(String input) {
|
|
ECIInteractionSpec interactionSpec = ...;
|
|
|
|
String output = (String) getCciTemplate().execute(interactionSpec,
|
|
new InteractionCallback() {
|
|
public Object doInInteraction(Interaction interaction, ConnectionFactory factory)
|
|
throws ResourceException {
|
|
Record input = new CommAreaRecord(inputString.getBytes());
|
|
Record output = new CommAreaRecord();
|
|
interaction.execute(holder.getInteractionSpec(), input, output);
|
|
return new String(output.toByteArray());
|
|
}
|
|
});
|
|
|
|
return output;
|
|
}
|
|
}</programlisting>
|
|
|
|
<para>For the examples above, the corresponding configuration of the
|
|
involved Spring beans could look like this in non-managed mode:</para>
|
|
|
|
<programlisting language="xml"><bean id="managedConnectionFactory" class="com.ibm.connector2.cics.ECIManagedConnectionFactory">
|
|
<property name="serverName" value="TXSERIES"/>
|
|
<property name="connectionURL" value="local:"/>
|
|
<property name="userName" value="CICSUSER"/>
|
|
<property name="password" value="CICS"/>
|
|
</bean>
|
|
|
|
<bean id="connectionFactory" class="org.springframework.jca.support.LocalConnectionFactoryBean">
|
|
<property name="managedConnectionFactory" ref="managedConnectionFactory"/>
|
|
</bean>
|
|
|
|
<bean id="component" class="mypackage.MyDaoImpl">
|
|
<property name="connectionFactory" ref="connectionFactory"/>
|
|
</bean></programlisting>
|
|
|
|
<para>In managed mode (that is, in a Java EE environment), the
|
|
configuration could look as follows:</para>
|
|
|
|
<programlisting language="xml"><jee:jndi-lookup id="connectionFactory" jndi-name="eis/cicseci"/>
|
|
|
|
<bean id="component" class="MyDaoImpl">
|
|
<property name="connectionFactory" ref="connectionFactory"/>
|
|
</bean></programlisting>
|
|
</section>
|
|
</section>
|
|
|
|
<section id="cci-object">
|
|
<title>Modeling CCI access as operation objects</title>
|
|
|
|
<para>The <literal>org.springframework.jca.cci.object</literal> package
|
|
contains support classes that allow you to access the EIS in a different
|
|
style: through reusable operation objects, analogous to Spring's JDBC
|
|
operation objects (see JDBC chapter). This will usually encapsulate the
|
|
CCI API: an application-level input object will be passed to the operation
|
|
object, so it can construct the input record and then convert the received
|
|
record data to an application-level output object and return it.</para>
|
|
|
|
<para><emphasis>Note</emphasis>: This approach is internally based on the
|
|
<classname>CciTemplate</classname> class and the
|
|
<interfacename>RecordCreator</interfacename> /
|
|
<interfacename>RecordExtractor</interfacename> interfaces, reusing the
|
|
machinery of Spring's core CCI support.</para>
|
|
|
|
<section id="cci-object-mapping-record">
|
|
<title><classname>MappingRecordOperation</classname></title>
|
|
|
|
<para><classname>MappingRecordOperation</classname> essentially performs
|
|
the same work as <classname>CciTemplate</classname>, but represents a
|
|
specific, pre-configured operation as an object. It provides two
|
|
template methods to specify how to convert an input object to a input
|
|
record, and how to convert an output record to an output object (record
|
|
mapping):</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para><literal>createInputRecord(..)</literal> to specify how to
|
|
convert an input object to an input
|
|
<interfacename>Record</interfacename></para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para><literal>extractOutputData(..)</literal> to specify how to
|
|
extract an output object from an output
|
|
<interfacename>Record</interfacename></para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>Here are the signatures of these methods:</para>
|
|
|
|
<programlisting language="java">public abstract class MappingRecordOperation extends EisOperation {
|
|
...
|
|
protected abstract Record createInputRecord(RecordFactory recordFactory, Object inputObject)
|
|
throws ResourceException, DataAccessException { ... }
|
|
|
|
protected abstract Object extractOutputData(Record outputRecord)
|
|
throws ResourceException, SQLException, DataAccessException { ... }
|
|
...
|
|
}</programlisting>
|
|
|
|
<para>Thereafter, in order to execute an EIS operation, you need to use
|
|
a single execute method, passing in an application-level input object
|
|
and receiving an application-level output object as result:</para>
|
|
|
|
<programlisting language="java">public abstract class MappingRecordOperation extends EisOperation {
|
|
...
|
|
public Object execute(Object inputObject) throws DataAccessException {
|
|
...
|
|
}</programlisting>
|
|
|
|
<para>As you can see, contrary to the <classname>CciTemplate</classname>
|
|
class, this <methodname>execute(..)</methodname> method does not have an
|
|
<interfacename>InteractionSpec</interfacename> as argument. Instead, the
|
|
<interfacename>InteractionSpec</interfacename> is global to the
|
|
operation. The following constructor must be used to instantiate an
|
|
operation object with a specific
|
|
<interfacename>InteractionSpec</interfacename>:</para>
|
|
|
|
<programlisting language="java">InteractionSpec spec = ...;
|
|
MyMappingRecordOperation eisOperation = new MyMappingRecordOperation(getConnectionFactory(), spec);
|
|
...</programlisting>
|
|
</section>
|
|
|
|
<section id="cci-object-mapping-comm-area">
|
|
<title><classname>MappingCommAreaOperation</classname></title>
|
|
|
|
<para>Some connectors use records based on a COMMAREA which represents
|
|
an array of bytes containing parameters to send to the EIS and data
|
|
returned by it. Spring provides a special operation class for working
|
|
directly on COMMAREA rather than on records. The
|
|
<classname>MappingCommAreaOperation</classname> class extends the
|
|
<classname>MappingRecordOperation</classname> class to provide such
|
|
special COMMAREA support. It implicitly uses the
|
|
<classname>CommAreaRecord</classname> class as input and output record
|
|
type, and provides two new methods to convert an input object into an
|
|
input COMMAREA and the output COMMAREA into an output object.</para>
|
|
|
|
<programlisting language="java">public abstract class MappingCommAreaOperation extends MappingRecordOperation {
|
|
...
|
|
protected abstract byte[] objectToBytes(Object inObject)
|
|
throws IOException, DataAccessException;
|
|
|
|
protected abstract Object bytesToObject(byte[] bytes)
|
|
throws IOException, DataAccessException;
|
|
...
|
|
}</programlisting>
|
|
</section>
|
|
|
|
<section id="cci-automatic-record-gen">
|
|
<title>Automatic output record generation</title>
|
|
|
|
<para>As every <classname>MappingRecordOperation</classname> subclass is
|
|
based on CciTemplate internally, the same way to automatically generate
|
|
output records as with <classname>CciTemplate</classname> is available.
|
|
Every operation object provides a corresponding
|
|
<literal>setOutputRecordCreator(..)</literal> method. For further
|
|
information, see <xref linkend="automatic-output-generation" />.</para>
|
|
</section>
|
|
|
|
<section id="cci-object-summary">
|
|
<title>Summary</title>
|
|
|
|
<para>The operation object approach uses records in the same manner as
|
|
the <classname>CciTemplate</classname> class.</para>
|
|
|
|
<table frame="all" id="cci-interaction-methods">
|
|
<title>Usage of Interaction execute methods</title>
|
|
|
|
<tgroup cols="3">
|
|
<thead>
|
|
<row>
|
|
<entry
|
|
align="center"><classname>MappingRecordOperation</classname>
|
|
method signature</entry>
|
|
|
|
<entry
|
|
align="center"><classname>MappingRecordOperation</classname>
|
|
<literal>outputRecordCreator</literal> property</entry>
|
|
|
|
<entry align="center">execute method called on the CCI
|
|
<interfacename>Interaction</interfacename></entry>
|
|
</row>
|
|
</thead>
|
|
|
|
<tbody>
|
|
<row>
|
|
<entry align="center">Object execute(Object)</entry>
|
|
|
|
<entry align="center">not set</entry>
|
|
|
|
<entry align="center">Record execute(InteractionSpec,
|
|
Record)</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry align="center">Object execute(Object)</entry>
|
|
|
|
<entry align="center">set</entry>
|
|
|
|
<entry align="center">boolean execute(InteractionSpec, Record,
|
|
Record)</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
</section>
|
|
|
|
<section id="cci-objects-mappring-record-example">
|
|
<title>Example for <classname>MappingRecordOperation</classname>
|
|
usage</title>
|
|
|
|
<para>In this section, the usage of the
|
|
<classname>MappingRecordOperation</classname> will be shown to access a
|
|
database with the Blackbox CCI connector.</para>
|
|
|
|
<note>
|
|
<para>The original version of this connector is provided by the Java EE
|
|
SDK (version 1.3), available from Sun.</para>
|
|
</note>
|
|
|
|
<para>Firstly, some initializations on the CCI
|
|
<interfacename>InteractionSpec</interfacename> must be done to specify
|
|
which SQL request to execute. In this sample, we directly define the way
|
|
to convert the parameters of the request to a CCI record and the way to
|
|
convert the CCI result record to an instance of the
|
|
<classname>Person</classname> class.</para>
|
|
|
|
<programlisting language="java">public class PersonMappingOperation extends MappingRecordOperation {
|
|
|
|
public PersonMappingOperation(ConnectionFactory connectionFactory) {
|
|
setConnectionFactory(connectionFactory);
|
|
CciInteractionSpec interactionSpec = new CciConnectionSpec();
|
|
interactionSpec.setSql("select * from person where person_id=?");
|
|
setInteractionSpec(interactionSpec);
|
|
}
|
|
|
|
protected Record createInputRecord(RecordFactory recordFactory, Object inputObject)
|
|
throws ResourceException {
|
|
Integer id = (Integer) inputObject;
|
|
IndexedRecord input = recordFactory.createIndexedRecord("input");
|
|
input.add(new Integer(id));
|
|
return input;
|
|
}
|
|
|
|
protected Object extractOutputData(Record outputRecord)
|
|
throws ResourceException, SQLException {
|
|
ResultSet rs = (ResultSet) outputRecord;
|
|
Person person = null;
|
|
if (rs.next()) {
|
|
Person person = new Person();
|
|
person.setId(rs.getInt("person_id"));
|
|
person.setLastName(rs.getString("person_last_name"));
|
|
person.setFirstName(rs.getString("person_first_name"));
|
|
}
|
|
return person;
|
|
}
|
|
}</programlisting>
|
|
|
|
<para>Then the application can execute the operation object, with the
|
|
person identifier as argument. Note that operation object could be set
|
|
up as shared instance, as it is thread-safe.</para>
|
|
|
|
<programlisting language="java">public class MyDaoImpl extends CciDaoSupport implements MyDao {
|
|
|
|
public Person getPerson(int id) {
|
|
PersonMappingOperation query = new PersonMappingOperation(getConnectionFactory());
|
|
Person person = (Person) query.execute(new Integer(id));
|
|
return person;
|
|
}
|
|
}</programlisting>
|
|
|
|
<para>The corresponding configuration of Spring beans could look as
|
|
follows in non-managed mode:</para>
|
|
|
|
<programlisting language="xml"><bean id="managedConnectionFactory"
|
|
class="com.sun.connector.cciblackbox.CciLocalTxManagedConnectionFactory">
|
|
<property name="connectionURL" value="jdbc:hsqldb:hsql://localhost:9001"/>
|
|
<property name="driverName" value="org.hsqldb.jdbcDriver"/>
|
|
</bean>
|
|
|
|
<bean id="targetConnectionFactory"
|
|
class="org.springframework.jca.support.LocalConnectionFactoryBean">
|
|
<property name="managedConnectionFactory" ref="managedConnectionFactory"/>
|
|
</bean>
|
|
|
|
<bean id="connectionFactory"
|
|
class="org.springframework.jca.cci.connection.ConnectionSpecConnectionFactoryAdapter">
|
|
<property name="targetConnectionFactory" ref="targetConnectionFactory"/>
|
|
<property name="connectionSpec">
|
|
<bean class="com.sun.connector.cciblackbox.CciConnectionSpec">
|
|
<property name="user" value="sa"/>
|
|
<property name="password" value=""/>
|
|
</bean>
|
|
</property>
|
|
</bean>
|
|
|
|
<bean id="component" class="MyDaoImpl">
|
|
<property name="connectionFactory" ref="connectionFactory"/>
|
|
</bean></programlisting>
|
|
|
|
<para>In managed mode (that is, in a Java EE environment), the
|
|
configuration could look as follows:</para>
|
|
|
|
<programlisting language="xml"><jee:jndi-lookup id="targetConnectionFactory" jndi-name="eis/blackbox"/>
|
|
|
|
<bean id="connectionFactory"
|
|
class="org.springframework.jca.cci.connection.ConnectionSpecConnectionFactoryAdapter">
|
|
<property name="targetConnectionFactory" ref="targetConnectionFactory"/>
|
|
<property name="connectionSpec">
|
|
<bean class="com.sun.connector.cciblackbox.CciConnectionSpec">
|
|
<property name="user" value="sa"/>
|
|
<property name="password" value=""/>
|
|
</bean>
|
|
</property>
|
|
</bean>
|
|
|
|
<bean id="component" class="MyDaoImpl">
|
|
<property name="connectionFactory" ref="connectionFactory"/>
|
|
</bean></programlisting>
|
|
</section>
|
|
|
|
<section id="cci-objects-mapping-comm-area-example">
|
|
<title>Example for <classname>MappingCommAreaOperation</classname>
|
|
usage</title>
|
|
|
|
<para>In this section, the usage of the
|
|
<classname>MappingCommAreaOperation</classname> will be shown: accessing
|
|
a CICS with ECI mode with the IBM CICS ECI connector.</para>
|
|
|
|
<para>Firstly, the CCI <interfacename>InteractionSpec</interfacename>
|
|
needs to be initialized to specify which CICS program to access and how
|
|
to interact with it.</para>
|
|
|
|
<programlisting language="java">public abstract class EciMappingOperation extends MappingCommAreaOperation {
|
|
|
|
public EciMappingOperation(ConnectionFactory connectionFactory, String programName) {
|
|
setConnectionFactory(connectionFactory);
|
|
ECIInteractionSpec interactionSpec = new ECIInteractionSpec(),
|
|
interactionSpec.setFunctionName(programName);
|
|
interactionSpec.setInteractionVerb(ECIInteractionSpec.SYNC_SEND_RECEIVE);
|
|
interactionSpec.setCommareaLength(30);
|
|
setInteractionSpec(interactionSpec);
|
|
setOutputRecordCreator(new EciOutputRecordCreator());
|
|
}
|
|
|
|
private static class EciOutputRecordCreator implements RecordCreator {
|
|
public Record createRecord(RecordFactory recordFactory) throws ResourceException {
|
|
return new CommAreaRecord();
|
|
}
|
|
}
|
|
}</programlisting>
|
|
|
|
<para>The abstract <classname>EciMappingOperation</classname> class can
|
|
then be subclassed to specify mappings between custom objects and
|
|
<literal>Records</literal>.</para>
|
|
|
|
<programlisting language="java">public class MyDaoImpl extends CciDaoSupport implements MyDao {
|
|
|
|
public OutputObject getData(Integer id) {
|
|
EciMappingOperation query = new EciMappingOperation(getConnectionFactory(), "MYPROG") {
|
|
protected abstract byte[] objectToBytes(Object inObject) throws IOException {
|
|
Integer id = (Integer) inObject;
|
|
return String.valueOf(id);
|
|
}
|
|
protected abstract Object bytesToObject(byte[] bytes) throws IOException;
|
|
String str = new String(bytes);
|
|
String field1 = str.substring(0,6);
|
|
String field2 = str.substring(6,1);
|
|
String field3 = str.substring(7,1);
|
|
return new OutputObject(field1, field2, field3);
|
|
}
|
|
});
|
|
|
|
return (OutputObject) query.execute(new Integer(id));
|
|
}
|
|
}</programlisting>
|
|
|
|
<para>The corresponding configuration of Spring beans could look as
|
|
follows in non-managed mode:</para>
|
|
|
|
<programlisting language="xml"><bean id="managedConnectionFactory" class="com.ibm.connector2.cics.ECIManagedConnectionFactory">
|
|
<property name="serverName" value="TXSERIES"/>
|
|
<property name="connectionURL" value="local:"/>
|
|
<property name="userName" value="CICSUSER"/>
|
|
<property name="password" value="CICS"/>
|
|
</bean>
|
|
|
|
<bean id="connectionFactory" class="org.springframework.jca.support.LocalConnectionFactoryBean">
|
|
<property name="managedConnectionFactory" ref="managedConnectionFactory"/>
|
|
</bean>
|
|
|
|
<bean id="component" class="MyDaoImpl">
|
|
<property name="connectionFactory" ref="connectionFactory"/>
|
|
</bean></programlisting>
|
|
|
|
<para>In managed mode (that is, in a Java EE environment), the
|
|
configuration could look as follows:</para>
|
|
|
|
<programlisting language="xml"><jee:jndi-lookup id="connectionFactory" jndi-name="eis/cicseci"/>
|
|
|
|
<bean id="component" class="MyDaoImpl">
|
|
<property name="connectionFactory" ref="connectionFactory"/>
|
|
</bean></programlisting>
|
|
</section>
|
|
</section>
|
|
|
|
<section id="cci-tx">
|
|
<title>Transactions</title>
|
|
|
|
<para>JCA specifies several levels of transaction support for resource
|
|
adapters. The kind of transactions that your resource adapter supports is
|
|
specified in its <filename>ra.xml</filename> file. There are essentially
|
|
three options: none (for example with CICS EPI connector), local
|
|
transactions (for example with a CICS ECI connector), global transactions
|
|
(for example with an IMS connector).</para>
|
|
|
|
<programlisting language="xml"><connector>
|
|
|
|
<resourceadapter>
|
|
|
|
<lineannotation><!-- <transaction-support>NoTransaction</transaction-support> --></lineannotation>
|
|
<lineannotation><!-- <transaction-support>LocalTransaction</transaction-support> --></lineannotation>
|
|
<transaction-support>XATransaction</transaction-support>
|
|
|
|
<resourceadapter>
|
|
|
|
<connector></programlisting>
|
|
|
|
<para>For global transactions, you can use Spring's generic transaction
|
|
infrastructure to demarcate transactions, with
|
|
<classname>JtaTransactionManager</classname> as backend (delegating to the
|
|
Java EE server's distributed transaction coordinator underneath).</para>
|
|
|
|
<para>For local transactions on a single CCI
|
|
<interfacename>ConnectionFactory</interfacename>, Spring provides a
|
|
specific transaction management strategy for CCI, analogous to the
|
|
<classname>DataSourceTransactionManager</classname> for JDBC. The CCI API
|
|
defines a local transaction object and corresponding local transaction
|
|
demarcation methods. Spring's
|
|
<classname>CciLocalTransactionManager</classname> executes such local CCI
|
|
transactions, fully compliant with Spring's generic
|
|
<interfacename>PlatformTransactionManager</interfacename>
|
|
abstraction.</para>
|
|
|
|
<programlisting language="xml"><jee:jndi-lookup id="eciConnectionFactory" jndi-name="eis/cicseci"/>
|
|
|
|
<bean id="eciTransactionManager"
|
|
class="org.springframework.jca.cci.connection.CciLocalTransactionManager">
|
|
<property name="connectionFactory" ref="eciConnectionFactory"/>
|
|
</bean></programlisting>
|
|
|
|
<para>Both transaction strategies can be used with any of Spring's
|
|
transaction demarcation facilities, be it declarative or programmatic.
|
|
This is a consequence of Spring's generic
|
|
<interfacename>PlatformTransactionManager</interfacename> abstraction,
|
|
which decouples transaction demarcation from the actual execution
|
|
strategy. Simply switch between
|
|
<classname>JtaTransactionManager</classname> and
|
|
<classname>CciLocalTransactionManager</classname> as needed, keeping your
|
|
transaction demarcation as-is.</para>
|
|
|
|
<para>For more information on Spring's transaction facilities, see the
|
|
chapter entitled <xref linkend="transaction" />.</para>
|
|
</section>
|
|
</chapter>
|