You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1158 lines
50 KiB
1158 lines
50 KiB
<?xml version="1.0" encoding="UTF-8"?> |
|
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" |
|
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd"> |
|
|
|
<chapter id="cci"> |
|
<title>JCA CCI</title> |
|
|
|
<section id="cci-introduction"> |
|
<title>Introduction</title> |
|
|
|
<para>J2EE provides a specification to standardize access to enterprise information systems (EIS): |
|
the JCA (Java 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 J2EE 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 J2EE 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> to 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 J2EE |
|
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"><![CDATA[<bean id="eciConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean"> |
|
<property name="jndiName" value="eis/cicseci"/> |
|
</bean>]]></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"><![CDATA[<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"><![CDATA[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"><![CDATA[<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"><![CDATA[<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"><![CDATA[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"><![CDATA[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"><![CDATA[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"><![CDATA[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"><![CDATA[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"><![CDATA[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"><![CDATA[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"><![CDATA[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"><![CDATA[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 the section entitled <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"><![CDATA[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"><![CDATA[<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"><![CDATA[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"><![CDATA[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"><![CDATA[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"><![CDATA[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"><![CDATA[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><![CDATA[ |
|
} |
|
}); |
|
} |
|
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"><![CDATA[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"><![CDATA[<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 J2EE environment), the configuration |
|
could look as follows:</para> |
|
|
|
<programlisting language="xml"><![CDATA[<bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean"> |
|
<property name="jndiName" value="eis/cicseci"/> |
|
</bean> |
|
|
|
<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"><![CDATA[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"><![CDATA[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"><![CDATA[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"><![CDATA[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 the section entitled <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 J2EE 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"><![CDATA[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"><![CDATA[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"><![CDATA[<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 J2EE environment), the configuration |
|
could look as follows:</para> |
|
|
|
<programlisting language="xml"><![CDATA[<bean id="targetConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean"> |
|
<property name="jndiName" value="eis/blackbox"/> |
|
</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> |
|
</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"><![CDATA[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"><![CDATA[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"><![CDATA[<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 J2EE environment), the configuration |
|
could look as follows:</para> |
|
|
|
<programlisting language="xml"><![CDATA[<bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean"> |
|
<property name="jndiName" value="eis/cicseci"/> |
|
</bean> |
|
|
|
<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"><![CDATA[<connector> |
|
|
|
<resourceadapter> |
|
|
|
]]><lineannotation><!-- <transaction-support>NoTransaction</transaction-support> --></lineannotation><![CDATA[ |
|
]]><lineannotation><!-- <transaction-support>LocalTransaction</transaction-support> --></lineannotation><![CDATA[ |
|
<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 J2EE 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"><![CDATA[<bean id="eciConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean"> |
|
<property name="jndiName" value="eis/cicseci"/> |
|
</bean> |
|
|
|
<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>
|
|
|