INT-1143, added transaction section to reference guuide
This commit is contained in:
@@ -72,6 +72,7 @@
|
||||
<xi:include href="./bridge.xml"/>
|
||||
<xi:include href="./gateway.xml"/>
|
||||
<xi:include href="./message-publishing.xml"/>
|
||||
<xi:include href="./transactions.xml"/>
|
||||
<xi:include href="./message-history.xml"/>
|
||||
<xi:include href="./file.xml"/>
|
||||
<xi:include href="./jdbc.xml"/>
|
||||
|
||||
134
src/docbkx/transactions.xml
Normal file
134
src/docbkx/transactions.xml
Normal file
@@ -0,0 +1,134 @@
|
||||
<?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="transactions">
|
||||
<title>Transaction Support</title>
|
||||
|
||||
<section id="transaction-support">
|
||||
<title>Understanding Transactions in Message flows</title>
|
||||
<para>
|
||||
Spring Integration exposes several hooks to address transactional needs of you message flows.
|
||||
But to better understand these hooks and how you can benefit from them we must first revisit the 6 mechanisms
|
||||
that could be used to initiate Message flows and see how transactional needs of these flows
|
||||
could be addressed within each of these mechanisms.
|
||||
</para>
|
||||
<para>
|
||||
Here are the 6 mechanisms to initiate a Message flow and their short summary (details for each are provided throughout this manual):
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><emphasis>Gateway Proxy</emphasis> - Your basic Messaging Gateway</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><emphasis>MessageChannel</emphasis> - Direct interactions with MessageChannel methods (e.g., channel.send(message))</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><emphasis>Message Publisher</emphasis> - the way to initiate message flow as a bi-product of method invocations on Spring beans</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><emphasis>Inbound Channel Adapters/Gateways</emphasis> - the way to initiate message flow based on connecting third-party
|
||||
system with Spring Integration messaging system(e.g., [JmsMessage] -> Jms Inbound Adapter[SI Message] -> SI Channel)</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><emphasis>Scheduler</emphasis> - the way to initiate message flow based on scheduling events distributed
|
||||
by a pre-configured Scheduler</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><emphasis>Poller</emphasis> - similar to the Scheduler and is the way to initiate message flow based on scheduling
|
||||
or interval-based events distributed by a pre-configured Poller</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<para>
|
||||
These 6 cold be split in 2 general categories:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><emphasis>Message flows initiated by a USER process</emphasis> - Example scenarios in this category
|
||||
would be invoking a Gateway method or explicitly sending a Message to a MessageChannel. In other words these message flows depend on third
|
||||
party process (e.g., some code that we wrote) to be initiated</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><emphasis>Message flows initiated by the DAEMON process</emphasis> - Example scenarios in this category would be a Poller
|
||||
polling for a Message queue to initiate a new Message flow with the polled Message or a Scheduler scheduling the
|
||||
process, by creating a new Message and initiating a message flow at a predefined time</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<para>
|
||||
Clearly the <emphasis>Gateway Proxy</emphasis>, <emphasis>MessageChannel.send(..)</emphasis> and <emphasis>MessagePublisher</emphasis> are
|
||||
all belong to the 1st category and <emphasis>Inbound Adapters/Gateways</emphasis>, <emphasis>Scheduler</emphasis> and <emphasis>Poller</emphasis> belong to the 2nd.
|
||||
</para>
|
||||
<para>
|
||||
So, how do we address transactional needs in various scenarios within each category and is there a need for Spring Integration
|
||||
to provide something explicitly with regard to transaction for a particular scenario or Spring's Transaction Support could be leveraged instead?.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
First of all, the first and obvious goal is NOT to re-invent something that has already been invented unless you can provide a beter solution.
|
||||
In our case Spring itself provides a first class support for transaction management. So our goal here is not to provide something new but rather
|
||||
delegate/use Spring to benefit from the existing support for transactions. In other words as a framework we must expose hooks to the Transaction management functionality
|
||||
provided by Spring. But since Spring Integration configuration is based on Spring Configuration it is not always neccessery to expose these hooks as they already
|
||||
expposed via Spring natively. Remeber every Spring Integration component is a Spring Bean after all.
|
||||
</para>
|
||||
<para>
|
||||
With this goal in mind let's look at the two scenarios.
|
||||
</para>
|
||||
<para>
|
||||
If you think about it, Message flows that are initiated by the <emphasis>USER process</emphasis> (Category 1) and obviously configured in Spring Application Context,
|
||||
are subject to transactional configuration of such process and therefore don't need to be explicitly configured by Spring Integration to support transactions.
|
||||
The transaction could and should be initiated by such process through standard Transaction support provided by Spring and Spring Integration message flow will honor
|
||||
transactional semantics of the components naturally because it is Spring configured. For example; A Gateway or ServiceActivator methods could
|
||||
be annotated with <classname>@Transactional</classname> or <classname>TransactionInterceptor</classname> could be configured in XML configuration
|
||||
with point-cut expression pointing to specific methods that should be transactional.
|
||||
The bottom line you have full control over transaction configuration and boundaries in these scenarios.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
However, things are a bit different when it comes to Message flows initiated by the <emphasis>DAEMON process</emphasis> (Category 2).
|
||||
Although configured by the developer these flows do not directly involve human or some other process to be initiated. These are trigger-based flows
|
||||
that are initiated by a trigger process (DAEMON process) based on the configuration of such process. For example, we could have a Scheduler
|
||||
initiating a message flow every Friday night of every week. We can also configure a trigger that initiates a Message flow every second, etc.
|
||||
So, we obviously need the same way to let these trigger-based processes know of our intention to make these Message flows transactional so
|
||||
Transaction context could be created whenever a new Message flow is initiated. In other words we need to expose some Transaction configuration, but ONLY enough
|
||||
to delegate to Transaction support already provided by Spring (as we do in other scenarios).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Spring Integration provides several hooks to accomplish this.
|
||||
</para>
|
||||
|
||||
<section id="transaction-poller">
|
||||
<title>Poller Transaction Support</title>
|
||||
<para>
|
||||
Any time you configure a Poller you can provide transactional configuration via <emphasis>transactional</emphasis> element and its attributes:
|
||||
<programlisting language="xml"><![CDATA[<poller max-messages-per-poll="1" fixed-rate="1000">
|
||||
<transactional transaction-manager="txManager"
|
||||
isolation="DEFAULT"
|
||||
propagation="REQUIRED"
|
||||
read-only="true"
|
||||
timeout="1000"/>
|
||||
</poller>]]></programlisting>
|
||||
As you can see this configuration looks evry similar to native Spring transaction configuration. You must still provide reference to Transaction manager and specify
|
||||
transaction attributes or rely on defauls (e.g., if 'transaction-manager'' attribute is not specified then it will default to the bean with the name 'transactionManager').
|
||||
Internally the process would be wrapped in the Spring's native Transaction where <classname>TransactionInterceptor</classname> is responsible to handle transactions.
|
||||
For more information on how to configure Transaction Manager, the types of Transaction Managers (e.g., JTA, Datasource etc.) and other details related to
|
||||
transaction configuration please refer to Spring's Reference manual (Chapter 10 - Transaction Management).
|
||||
</para>
|
||||
<para>
|
||||
With the above configuration all Message flows initiated by this poller will be transactional. For more information and details on
|
||||
Poller's transactional configuration please refer to section - <emphasis>21.1.1. Polling and Transactions</emphasis>.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
<section id="transaction-boundaries">
|
||||
<title>Transaction Boundaries</title>
|
||||
<para>
|
||||
Another important factor that needs to be understood is the boundaries of the Transactions within the Message flow.
|
||||
When transaction is started, transaction context is bound to the current thread. So regardless of how many endpoints and channels you have in your
|
||||
Message flow you transaction context will be preserved as long as you are ensuring that the flow continues on the same thread.
|
||||
As soon as you break it by introducing a <emphasis>Pollable Channel</emphasis> or <emphasis>Executor Channel</emphasis> or initiate a new thread manually in some
|
||||
service, the Transactional boundary will be broken as well. Essentially the Transaction will END right there and if
|
||||
successfull hand of happened between the threads, the flow would be considered a success and COMMIT signal would be sent
|
||||
even though the flow might still result in the exception somewhere downstream. If such flow was synchronous the exception would be thrown back to the
|
||||
initiator of the Message flow who is also the initiator of the transactional context and transaction would result in a ROLLBACK.
|
||||
</para>
|
||||
</section>
|
||||
</chapter>
|
||||
Reference in New Issue
Block a user