diff --git a/src/reference/docbook/transactions.xml b/src/reference/docbook/transactions.xml
index 0fa15248a6..9cd93f6dff 100644
--- a/src/reference/docbook/transactions.xml
+++ b/src/reference/docbook/transactions.xml
@@ -174,16 +174,118 @@ as a convinience.
-
- Pollers and Transaction Synchronization
+
+ Transaction Synchronization
- Certain inbound adapters are capable of synchronizing their updates with a transaction. For example, the mail
- inbound adapters, if running in a transaction and configured to mark or delete messages, will only take those
- actions on a mail message if the transaction commits; otherwise the mail message is left in the inbox.
+ In some environments, it is advantageous to synchronize operations with a transaction that encompasses the entire flow.
+ For example, consider a <file:inbound-channel-adapter/> at the start of a flow, that performs a number of database
+ updates. If the transaction commits, we might want to move the file to a success directory, while we
+ might want to move it to a failures directory if the transaction rolls back.
- For all message sources that implement PseudoTransactionalMessageSource, this is the default behavior (commit and
- rollback detection). It can be disabled by setting the synchronized attribute on the poller to false.
+ Spring Integration 2.2 introduces the capability of synchronizing these operations with a transaction. In addition, you
+ can configure a PseudoTransactionManager if you don't have a 'real' transaction, but still want
+ to perform different actions on success, or failure. For more information, see .
+
+
+ Key strategy interfaces for this feature are
+
+
+ The factory is responsible for creating a
+ TransactionSynchronization
+ object. You can implement your own, or use the one provided by the framework:
+ DefaultTransactionSynchronizationFactory. This implementation returns a
+ TransactionSynchronization that delegates to a default implementation of
+ TransactionSynchronizationProcessor, the
+ ExpressionEvaluatingTransactionSynchronizationProcessor. This processor supports three SpEL expressions,
+ beforeCommitExpression, afterCommitExpression, and afterRollbackExpression.
+
+
+ These actions should be self-explanatory to those familiar with transactions. In each case, the #root
+ variable is the original Message; in some cases, other SpEL variables are made available, depending on the
+ MessageSource being polled by the poller. For example, the MongoDbMessageSource
+ provides the #mongoTemplate variable which references the message source's
+ MongoTemplate; the RedisStoreMessageSource provides the #store
+ variable which references the RedisStore created by the poll.
+
+
+ To enable the feature for a particular poller, you provide a reference to the TransactionSynchronizationFactory
+ on the poller's <transactional/> element using the synchronization-factory attribute.
+
+
+ To simplify configuration of these components, namespace support for the default factory has been provided. Configuration is best
+ described using an example:
+
+
+
+
+
+
+
+
+
+
+]]>
+
+ The result of the SpEL evaluation is sent as the payload to either the committedChannel
+ or rolledBackChannel (in this case, this would be Boolean.TRUE or
+ Boolean.FALSE - the result of the
+ java.io.File.renameTo() method call).
+
+
+ If you wish to send the entire payload for further Spring Integration processing, simply use the expression
+ 'payload'.
+
+
+ It is important to understand that this is simply synchronizing the actions with a transaction, it does not
+ make a resource that is not inherently transactional actually transactional. Instead, the transaction
+ (be it JDBC or otherwise) is started before the poll, and committed/rolled back when the flow completes,
+ followed by the synchronized action.
+
+
+ In addition to the after-commit and after-rollback expressions,
+ before-commit is also supported. In that case, if the evaluation (or downstream processing)
+ throws an exception, the transaction will be rolled back instead of being committed.
+
+ Pseudo Transactions
+
+ Referring to the above section, you may be thinking it would be useful to take these 'success' or 'failure'
+ actions when a flow completes, even if there is no 'real' transactional resources (such as JDBC) downstream
+ of the poller. For example, consider a <file:inbound-channel-adapter/> followed by an
+ <ftp:outbout-channel-adapter/>. Neither of these components is transactional but we might want to
+ move the input file to different directories, based on the success or failure of the ftp transfer.
+
+
+ To provide this functionality, the framework provides a PseudoTransactionManager,
+ enabling the above configuration even when there is no real transactional resource involved. If the flow
+ completes normally, the beforeCommit and afterCommit synchronizations
+ will be called, on failure the afterRollback will be called. Of course, because it
+ is not a real transaction there will be no actual commit or rollback. The pseudo transaction is simply
+ a vehicle used to enable the synchronization features.
+
+
+ To use a PseudoTransactionManager, simply define it as a <bean/>, in the same
+ way you would configure a real transaction manager:
+
+ ]]>
+
diff --git a/src/reference/docbook/whats-new.xml b/src/reference/docbook/whats-new.xml
index c2f2ce05ad..016bb2ae86 100644
--- a/src/reference/docbook/whats-new.xml
+++ b/src/reference/docbook/whats-new.xml
@@ -138,6 +138,21 @@
For more information, see .
+
+ Transaction Synchronization and Pseudo Transactions
+
+ Pollers can now participate in Spring's Transaction Synchronization
+ feature. This allows for synchronizing such operations as renaming files by an inbound channel
+ adapter depending on whether the transaction commits, or rolls back.
+
+
+ In addition, these features can be enabled when there is not a 'real' transaction present,
+ by means of a PseudoTransactionManager.
+
+
+ For more information see .
+
+