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.
1190 lines
51 KiB
1190 lines
51 KiB
<?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>
|
|
|