Comprehensive transaction support is one of the most compelling reasons to use the Spring Framework. The Spring Framework provides a consistent abstraction for transaction management that provides the following benefits:

  • Consistent programming model for various transaction APIs such as Java Transaction API (JTA), JDBC, Hibernate, and Java Persistence API (JPA).

  • Support for declarative transaction management.

  • Simplified API for programmatic transaction management instead of complex transaction APIs such as JTA.

  • Excellent integration with Spring data access abstractions.

Benefits of the Spring Framework transaction support model

Traditionally, Java EE developers have had two options for managing transactions: through global or local transactions, both of which have serious limitations. Global and local transaction management are discussed in the next two sections, followed by a description of how the Spring Framework's transaction management support overcomes the limitations of the global and local transaction models.

Global transactions

Global transactions allow you to work with multiple transactional resources, typically relational databases and message queues. The application server manages global transactions via JTA, which is a cumbersome API (partly due to its exception model). Additionally, UserTransaction from JTA usually needs to be retrieved from JNDI, which means that you also have to use JNDI to use JTA. The use of global transactions limits any potential reuse of application code, since JTA is typically only available in the application server environment.

Previously, the preferred way to use global transactions was using EJB Container Managed Transactions (CMT). CMT is a form of declarative transaction management (as opposed to programmatic transaction management). CMT from EJB eliminates the need for transaction-related lookups through JNDI, although using EJB itself requires the use of JNDI. This eliminates most, although not entirely, the need to write Java code to manage transactions. A significant drawback is that CMT is tied to the JTA and application server environment. Additionally, it is only available if you choose to implement business logic within EJB classes (or at least within the EJB transactional façade). The disadvantages of EJB in general are so significant that its use ceases to be attractive, especially when compared with adequate alternatives for declarative transaction management.

Local transactions

Local transactions are resource specific, as is the case with a transaction associated with a JDBC connection. Local transactions can be easier to use, but have a significant drawback: They cannot handle multiple transactional resources. For example, code that manages transactions using a JDBC connection cannot run in a global JTA transaction. Because the application server is not involved in transaction management, it cannot ensure the correct operation of multiple resources. (It's worth noting that most applications use a single transaction resource.) Another disadvantage is that local transactions are aggressive in their programming model.

The Spring Framework consistent programming model

Spring eliminates the shortcomings of global and local transactions. This allows application developers to use a consistent programming model in any environment. You write your code once, and it, in turn, can use different transaction management strategies in different environments. The Spring Framework provides both declarative and programmatic transaction management. Most users prefer declarative transaction management, which is what we recommend in most cases.

When managing transactions programmatically, developers deal with the Spring Framework transaction abstraction, which can run on any underlying transaction infrastructure. When using the preferred declarative model, developers typically write little or no code related to transaction management, and therefore do not depend on the transaction API from the Spring Framework or any other transaction API.

Do you need an application server to manage transactions?

The Spring Framework's support for transaction management changes the traditional rules regarding the requirement for an application server for a Java application.

In particular, if we are talking exclusively about declarative transactions through EJB classes, an application server is not required. In fact, even if your application server has full-featured JTA capabilities, you may still find that the Spring Framework's declarative transactions provide more functionality and a more productive programming model than EJB's CMT.

Typically, an application server's JTA capabilities are only required if the application needs to process transactions across multiple resources, which is not a requirement for many applications. Many high-end applications instead use a single, highly scalable database (such as Oracle RAC). Standalone transaction managers (such as Atomikos Transactions and JOTM) are another option. Of course, other application server tools may be required, such as the Java Message Service (JMS) and the Java EE Connector Architecture (JCA).

The Spring Framework allows you to choose when to scale your application to a fully loaded application server. Gone are the days when the only alternative to using CMT from EJB or JTA was to write code with local transactions (such as JDBC connections) and have to deal with significant code rewriting if you want that code to run within the boundaries of container-managed global transactions. In the Spring Framework, you only need to change some of the bean definitions in the configuration file (not the code).