Chapter 8. Transactions and Idempotency

In this chapter, we will cover the following recipes:

  • Preventing duplicate invocation of routing logic
  • Transactional file consumption
  • Using transactions with a database
  • Limiting the scope of a transaction
  • Rolling back a transaction
  • Using transactions with messaging
  • Idempotency inside transactions
  • Setting up XA transactions over multiple transactional resources

Introduction

Systems integration is all about coordinating the interaction between multiple systems in order for them to interact as a larger whole. This interaction forms a distributed system, although people working on integrations tend not to think about what they are building in those terms. Part of the complexity of distributed systems is that they are typically written by different people at different times, using different technologies, doing things in parallel, and yet they need to coordinate on shared tasks. They also need to handle errors in a predictable fashion when that coordination breaks down. All of these factors make work on integrations very challenging, and very interesting.

A Transaction is an implementation concept that allows distributed stateful nodes in a system, such as databases and message brokers, to coordinate changes to their state. Updates to state are either committed when a unit of work has been completed successfully, or rolled back when an error occurs. This concept is especially helpful when you start thinking about all of the corner cases where things could go wrong, such as a network cable being tripped over, or a server having coffee spilled on it (it happens).

Your integrations need to maintain the overall integrity of the data travelling through the system at all times. This includes any of the messages that happen to be in-flight through your integration logic when your application process is unexpectedly terminated.

When developing integrations, you need to consider two primary issues, which are stated as follows:

  • Partner systems will go down. When a customer is placing an order online, it is not satisfactory for them to be billed and then not to have the items sent because the warehouse system was unavailable.
  • The process running your integration logic will also go down. If a client is billed for an order, and your integration shuts down before you are able to send the order to the warehouse, you need to be able to recover. This needs to happen in such a way that they are not billed twice and eventually get their order, or that the payment is unwound.

In this chapter, we will look at Camel's support for handling failures in your routing logic through the following mechanisms:

  • Transactions
  • Idempotency: It executes an operation once and once only

For the purpose of executing transactions, Camel makes use of the Spring framework's PlatformTransactionManager. This abstraction unifies the API for dealing with transactional resources. Use of the Spring transaction abstractions happens regardless of whether your application code directly uses Spring.

To use JDBC transactions in your projects, you will need a JdbcTransactionManager connection. This can be imported through a dependency on the spring-jdbc library in your Maven POM:

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-jdbc</artifactId>
  <version>${spring-version}</version>
</dependency>

To use JMS transactions in your projects, you will need a JmsTransactionManager connection. This can be imported through a dependency on the spring-jms library in your Maven POM:

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-jms</artifactId>
  <version>${spring-version}</version>
</dependency>

In both cases, ${spring-version} is a property that you define in the properties section of your POM that states which version of Spring you are using.

Where database access is required in these examples, the Camel SQL Component is used. This component provides the simplest method of demonstrating transactional database access in Camel. Other components that abstract relational database access, such as Camel JPA (Java Persistence Architecture), Camel Hibernate, or Camel Mybatis, will require slightly different configuration, though the general approach shown here will still be valid.

A number of Camel architectural concepts are used throughout this chapter. There is a broader overview of Camel concepts in the Preface. Full details can be found on the Apache Camel website at http://camel.apache.org.

The code for this chapter is contained within the camel-cookbook-transactions module of the examples.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.141.31.125