diff --git a/src/docbkx/index.xml b/src/docbkx/index.xml index f7f75ad075..ceab56dd45 100644 --- a/src/docbkx/index.xml +++ b/src/docbkx/index.xml @@ -72,6 +72,7 @@ + diff --git a/src/docbkx/transactions.xml b/src/docbkx/transactions.xml new file mode 100644 index 0000000000..2a563f2289 --- /dev/null +++ b/src/docbkx/transactions.xml @@ -0,0 +1,134 @@ + + + + Transaction Support + +
+ Understanding Transactions in Message flows + + 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. + + + Here are the 6 mechanisms to initiate a Message flow and their short summary (details for each are provided throughout this manual): + + + Gateway Proxy - Your basic Messaging Gateway + + + MessageChannel - Direct interactions with MessageChannel methods (e.g., channel.send(message)) + + + Message Publisher - the way to initiate message flow as a bi-product of method invocations on Spring beans + + + Inbound Channel Adapters/Gateways - 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) + + + Scheduler - the way to initiate message flow based on scheduling events distributed + by a pre-configured Scheduler + + + Poller - 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 + + + + + These 6 cold be split in 2 general categories: + + + Message flows initiated by a USER process - 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 + + + Message flows initiated by the DAEMON process - 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 + + + + + Clearly the Gateway Proxy, MessageChannel.send(..) and MessagePublisher are + all belong to the 1st category and Inbound Adapters/Gateways, Scheduler and Poller belong to the 2nd. + + + 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?. + + + + 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. + + + With this goal in mind let's look at the two scenarios.  + + + If you think about it, Message flows that are initiated by the USER process (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 @Transactional or TransactionInterceptor 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. + + + + However, things are a bit different when it comes to Message flows initiated by the DAEMON process (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). + + + + Spring Integration provides several hooks to accomplish this. + + +
+ Poller Transaction Support + + Any time you configure a Poller you can provide transactional configuration via transactional element and its attributes: + + +]]> + 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 TransactionInterceptor 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). + + + 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 - 21.1.1. Polling and Transactions. + +
+
+
+ Transaction Boundaries + + 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 Pollable Channel or Executor Channel 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. + +
+
\ No newline at end of file