INTSAMPLES-91 Transaction Synchronization Sample
INTSAMPLES-91 Initial Commit INTSAMPLES-91 Polishing INTSAMPLES-91 Add JDBC Activity
This commit is contained in:
@@ -62,6 +62,7 @@ This category targets developers who are already more familiar with the Spring I
|
||||
* **stored-procedures-oracle** Provides an example of the stored procedure Outbound Gateway using *ORACLE XE*
|
||||
* **monitoring** The project used in the *[Spring Integration Management and Monitoring Webinar](http://www.springsource.org/node/3598)* Also available on the *[SpringSourceDev YouTube Channel](http://www.youtube.com/SpringSourceDev)*
|
||||
* **retry-and-more** Provides samples showing the application of MessageHandler Advice Chains to endpoints - retry, circuit breaker, expression evaluating
|
||||
* **tx-synch** Provides a sample demonstrating the use of transaction syncrhonization, renaming an input file to a different filename, depending on whether the transaction commits, or rolls back.
|
||||
|
||||
## Advanced
|
||||
|
||||
|
||||
48
intermediate/tx-synch/README.md
Executable file
48
intermediate/tx-synch/README.md
Executable file
@@ -0,0 +1,48 @@
|
||||
Transaction Synchronization Sample "tx-synch"
|
||||
=============================================
|
||||
|
||||
This sample shows how to use the 2.2.0 Transaction Synchronization feature.
|
||||
|
||||
Run the class `TransactionSynchronizationDemo` as a java application (main).
|
||||
|
||||
The Spring Integration application consists of a simple flow that reads a file, and stores its contents in a database table.
|
||||
|
||||
If the contents of the file starts with "fail", after writing to the database, the 'ConditionalService' throws an exception and rolls back the database update.
|
||||
|
||||
There are two synchronization actions
|
||||
|
||||
- rename the file, adding '.SUCCEEDED' to the filename when the transaction commits
|
||||
- rename the file, adding '.FAILED' to the filename when the transaction rolls back
|
||||
|
||||
These actions are logged.
|
||||
|
||||
The file inbound adapter looks for files in ${java.io.tmpdir}/txSynchDemo
|
||||
|
||||
The java.io.tmpdir for your machine is displayed in the console…
|
||||
|
||||
````
|
||||
This is the Transaction Synchronization Sample -
|
||||
|
||||
Press 'Enter' to terminate.
|
||||
|
||||
Place a file in /var/folders/k0/gch26h6d2ms9t0g7pyhtzfkc0000gn/T/txSynchDemo ending
|
||||
with .txt
|
||||
If the first line begins with 'fail' the transaction
|
||||
transaction will be rolled back.The result of the
|
||||
expression evaluation is logged.
|
||||
|
||||
=========================================================
|
||||
/var/folders/k0/gch26h6d2ms9t0g7pyhtzfkc0000gn/T/txSynchDir
|
||||
````
|
||||
|
||||
To send a good file, put a file in that directory; for example:
|
||||
|
||||
echo good > /var/folders/k0/gch26h6d2ms9t0g7pyhtzfkc0000gn/T/txSynchDemo/xx.txt
|
||||
|
||||
echo failing > /var/folders/k0/gch26h6d2ms9t0g7pyhtzfkc0000gn/T/txSynchDemo/x.txt
|
||||
|
||||
|
||||
The inbound adapter uses the default filters so each filename may only be used once for each run of the program.
|
||||
|
||||
|
||||
In addition, there is a JDBC inbound adapter that polls the database every 5 seconds, and logs its contents - this can be used to see commit Vs. rollback in the database.
|
||||
102
intermediate/tx-synch/pom.xml
Executable file
102
intermediate/tx-synch/pom.xml
Executable file
@@ -0,0 +1,102 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.integration.samples</groupId>
|
||||
<artifactId>tx-synch</artifactId>
|
||||
<version>2.1.0.BUILD-SNAPSHOT</version>
|
||||
<name>Samples (Intermediate) - Transaction Synchronization</name>
|
||||
<packaging>jar</packaging>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<spring.framework.version>3.1.2.RELEASE</spring.framework.version>
|
||||
<spring.integration.version>2.2.0.RC1</spring.integration.version>
|
||||
<log4j.version>1.2.16</log4j.version>
|
||||
<junit.version>4.10</junit.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-stream</artifactId>
|
||||
<version>${spring.integration.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-jdbc</artifactId>
|
||||
<version>${spring.integration.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-file</artifactId>
|
||||
<version>${spring.integration.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-ftp</artifactId>
|
||||
<version>${spring.integration.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jdbc</artifactId>
|
||||
<version>${spring.framework.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>1.3.166</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>${log4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<version>1.8.5</version>
|
||||
</dependency>
|
||||
<!-- test-scoped dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>${spring.framework.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>2.3.2</version>
|
||||
<configuration>
|
||||
<source>1.5</source>
|
||||
<target>1.5</target>
|
||||
<compilerArgument>-Xlint:all</compilerArgument>
|
||||
<showWarnings>true</showWarnings>
|
||||
<showDeprecation>false</showDeprecation>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>1.2</version>
|
||||
<configuration>
|
||||
<mainClass>${java.main.class}</mainClass>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>repo.springsource.org.milestone</id>
|
||||
<name>Spring Framework Maven Milestone Repository</name>
|
||||
<url>https://repo.springsource.org/libs-snapshot</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
</project>
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.integration.samples.advice;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
/**
|
||||
* @author Gary Russell
|
||||
* @since 2.2
|
||||
*
|
||||
*/
|
||||
public class ConditionalService {
|
||||
|
||||
@Autowired
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
|
||||
private final Log logger = LogFactory.getLog(this.getClass());
|
||||
|
||||
/**
|
||||
* If this service receives a payload 'fail.*' it throws an Exception.
|
||||
* @param payload
|
||||
*/
|
||||
public void failIfTextIsFail(String payload) {
|
||||
this.jdbcTemplate.update("insert into FOO values(?)", payload);
|
||||
if (payload.startsWith("fail")) {
|
||||
logger.info("Service failure for " + payload);
|
||||
throw new RuntimeException("Forced Exception");
|
||||
}
|
||||
logger.info("Service success for " + payload);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.integration.samples.advice;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.context.support.AbstractApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
/**
|
||||
* @author Gary Russell
|
||||
* @since 2.2
|
||||
*
|
||||
*/
|
||||
public class TransactionSynchronizationDemo {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(TransactionSynchronizationDemo.class);
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
LOGGER.info("\n========================================================="
|
||||
+ "\n "
|
||||
+ "\n Welcome to Spring Integration! "
|
||||
+ "\n "
|
||||
+ "\n For more information please visit: "
|
||||
+ "\n http://www.springsource.org/spring-integration "
|
||||
+ "\n "
|
||||
+ "\n=========================================================" );
|
||||
|
||||
final AbstractApplicationContext context =
|
||||
new ClassPathXmlApplicationContext("classpath:META-INF/spring/integration/transaction-synch-context.xml");
|
||||
|
||||
context.registerShutdownHook();
|
||||
|
||||
LOGGER.info("\n========================================================="
|
||||
+ "\n "
|
||||
+ "\n This is the Transaction Synchronization Sample - "
|
||||
+ "\n "
|
||||
+ "\n Press 'Enter' to terminate. "
|
||||
+ "\n "
|
||||
+ "\n Place a file in " + System.getProperty("java.io.tmpdir") + "/txSynchDemo ending "
|
||||
+ "\n with .txt "
|
||||
+ "\n If the first line begins with 'fail' the transaction "
|
||||
+ "\n transaction will be rolled back.The result of the "
|
||||
+ "\n expression evaluation is logged. "
|
||||
+ "\n "
|
||||
+ "\n=========================================================" );
|
||||
System.out.println(System.getProperty("java.io.tmpdir") + "/txSynchDir");
|
||||
System.in.read();
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:int-stream="http://www.springframework.org/schema/integration/stream"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:int-file="http://www.springframework.org/schema/integration/file"
|
||||
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
|
||||
xmlns:int-jdbc="http://www.springframework.org/schema/integration/jdbc"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/integration/file http://www.springframework.org/schema/integration/file/spring-integration-file.xsd
|
||||
http://www.springframework.org/schema/integration/jdbc http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc-2.2.xsd
|
||||
http://www.springframework.org/schema/integration/stream http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
|
||||
|
||||
<context:annotation-config />
|
||||
|
||||
<context:property-placeholder />
|
||||
|
||||
<int-file:inbound-channel-adapter
|
||||
channel="inputChannel"
|
||||
auto-create-directory="true"
|
||||
filename-pattern="*.txt"
|
||||
directory="${java.io.tmpdir}/txSynchDemo/">
|
||||
<int:poller fixed-delay="500">
|
||||
<int:transactional transaction-manager="txManager" synchronization-factory="syncFactory" />
|
||||
</int:poller>
|
||||
</int-file:inbound-channel-adapter>
|
||||
|
||||
<int:transaction-synchronization-factory id="syncFactory">
|
||||
<int:after-commit expression="payload.renameTo(payload.absolutePath + '.SUCCEEDED') ? payload + ' renamed after success' : payload + 'failed to rename after success'"
|
||||
channel="infoLogger" />
|
||||
<int:after-rollback expression="payload.renameTo(payload.absolutePath + '.FAILED') ? payload + ' renamed after faiure' : payload + 'failed to rename after failure'"
|
||||
channel="errorLogger" />
|
||||
</int:transaction-synchronization-factory>
|
||||
|
||||
<int:channel id="inputChannel"/>
|
||||
|
||||
<int-file:file-to-string-transformer input-channel="inputChannel" output-channel="toServiceChannel" />
|
||||
|
||||
<int:service-activator input-channel="toServiceChannel"
|
||||
ref="conditionalService"
|
||||
method="failIfTextIsFail" />
|
||||
|
||||
<int:logging-channel-adapter id="infoLogger" level="INFO" />
|
||||
|
||||
<int:logging-channel-adapter id="errorLogger" level="ERROR" />
|
||||
<bean id="conditionalService" class="org.springframework.integration.samples.advice.ConditionalService" />
|
||||
|
||||
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
|
||||
<property name="dataSource" ref="dataSource" />
|
||||
</bean>
|
||||
|
||||
<jdbc:embedded-database id="dataSource" type="H2">
|
||||
<jdbc:script location="classpath:table.sql" />
|
||||
</jdbc:embedded-database>
|
||||
|
||||
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
|
||||
<property name="dataSource" ref="dataSource" />
|
||||
</bean>
|
||||
|
||||
<!-- Poll the database for rows -->
|
||||
|
||||
<int-jdbc:inbound-channel-adapter channel="infoLogger"
|
||||
query="select BAR from FOO" data-source="dataSource">
|
||||
<int:poller fixed-delay="5000" />
|
||||
</int-jdbc:inbound-channel-adapter>
|
||||
</beans>
|
||||
44
intermediate/tx-synch/src/main/resources/log4j.xml
Executable file
44
intermediate/tx-synch/src/main/resources/log4j.xml
Executable file
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
|
||||
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
|
||||
|
||||
<!-- Appenders -->
|
||||
<appender name="console" class="org.apache.log4j.ConsoleAppender">
|
||||
<param name="Target" value="System.out" />
|
||||
<layout class="org.apache.log4j.PatternLayout">
|
||||
<param name="ConversionPattern" value="%d{HH:mm:ss.SSS} %-5p [%t][%c] %m%n" />
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<!-- Loggers -->
|
||||
<logger name="org.springframework">
|
||||
<level value="warn" />
|
||||
</logger>
|
||||
|
||||
<logger name="org.springframework.integration.endpoint.SourcePollingChannelAdapter">
|
||||
<level value="warn" />
|
||||
</logger>
|
||||
|
||||
<logger name="org.springframework.integration">
|
||||
<level value="warn" />
|
||||
</logger>
|
||||
|
||||
<logger name="org.springframework.integration.handler.LoggingHandler">
|
||||
<level value="info" />
|
||||
</logger>
|
||||
|
||||
<logger name="org.springframework.integration.samples">
|
||||
<level value="info" />
|
||||
</logger>
|
||||
|
||||
<logger name="org.springframework.retry">
|
||||
<level value="warn" />
|
||||
</logger>
|
||||
|
||||
<!-- Root Logger -->
|
||||
<root>
|
||||
<priority value="warn" />
|
||||
<appender-ref ref="console" />
|
||||
</root>
|
||||
|
||||
</log4j:configuration>
|
||||
4
intermediate/tx-synch/src/main/resources/table.sql
Normal file
4
intermediate/tx-synch/src/main/resources/table.sql
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
CREATE TABLE IF NOT EXISTS FOO (
|
||||
BAR VARCHAR(256)
|
||||
);
|
||||
Reference in New Issue
Block a user