Spring Declarative Transactions Example

A transaction is a unit of work that has ACID (atomic, consistent, isolated and durable) properties. Atomic means that the changes all happen or nothing happens. If money is debited from an account and credited to another account, a transaction ensures that either both the debit and credit complete or neither completes. Consistent implies that the changes leave the data in a consistent state. Isolated implies that changes do not interfere with other changes. Durable implies that once the changes are committed, they stay committed.

Resource managers such as relation databases provide a transaction manager and an API to control transactions. Those familiar with JDBC will know that by default a transaction is started because of the setting autocommit= true. Every statement that changes the database is automatically committed. This behavior can be changed by setting autocommit to false. Now the programmer must explicitly begin a transaction and then commit or rollback the transaction.

Transactions that deal with just one resource such as one database are known as local transactions. Transactions that span multiple resources such as more than one database or a database and a messaging engine are called global transactions. Global transaction are implemented using the XA protocol which involves a two phase commit. The JTA specification describes a Java API for programmers to work with global transactions. The transaction methods in JDBC such as begin, commit, rollback work only with JDBC and relational databases, where as JTA can work with any transactional resource.

The code involved in working with transactions, however is boiler plate code that can be handled by a framework. At the start of the method, you need to begin a transaction and when the method completes, you need to either commit or rollback the transaction. If you have worked with EJBs, you might be familiar that you can specify in the deployment descriptor, the transactional environment in which the method should execute. For example you might say RequiresNew, which means start a new transaction before invoking the method. The container starts a new transaction before the method is invoked and commits it when the method returns. The programmer does not need to write any java code to handle transaction.

In rest of the article, we discuss with an example, declarative transaction management with Spring.

For this tutorial you will need:

(1) Spring 3.0
(2) Eclipse is optional. I use eclipse as my IDE. Eclipse lets you export the war that can be deployed to Tomcat. But you can use other IDEs or command line tools as well.
(3) You may download the source code for this example at springjdbcwithTransaction.zip.

We resuse the example from the JDBC with Spring blog we wrote some time ago. Let us add transactions support to MemberSpringJDBCDAO. This class has the insertMember method that inserts a member to the database. Let us modify the method a little bit to throw a RuntimeException after the insert into the database. The runtime exception is added to pretend that an error occured in business logic while updating the database.

public int insertMember(Member member) {
    JdbcTemplate jt = getJdbcTemplate() ;
    Object[] params = new Object[{member.getFirstname(),
        member.getLastname(),
        member.getStreet(),member.getCity(),
        member.getZip(),member.getEmail(),member.getPassword()} ;
  
    int ret = jt.update(insert_sql, params) ;
    throw new RuntimeException("simulate Error condition') ;
    return ret ;
}

In this method, would you expect the insert to be committed to the database ? The answer is Yes, though that is not the desirable behavior. The default behaviour of JDBC is autocommit = true , which means, each insert or update is committed immediately. You could set autocommit = false and explicitly commit or rollback at the end of the method. But it is much easier to let your container handle this.

To add declarative transaction management to the above method use the following steps:

Step 1: Define a transaction manager in springjdbcdao.xml

<bean id="txManager"
	class="org.springframework.jdbc.datasource.DataSourceTransactionManager"/> 

Spring works with the transaction manager to begin and complete transactions.

Step 2: Turn on support for transaction annotations

Add to springjdbcdao.xml

<tx:annotation-driven transaction-manager="txManager"/>

Step 3: Add the @Transactional annotation to the insertMember method

@Transactional
public int insertMember(Member member) {
...	

@Transactional can take properties but we will go with default values which are:

Propagation : Required

Required means a transaction is required. If there is no transaction, Spring requests the transaction manager to start one. The other possible values is Requires_New, which tells the transaction manager to always suspend the existing transaction and start a new one.

Isolation level : Default

Use the default isolation level of the underlying resource manager.

Rollback : Any runtime exception triggers a rollback

Step 4: Run the updated insertMember method using Junit test MemberSpringJDBCDAOTest.

You will see the following logs from the transaction manager indicating the transaction rolled back.

org.springframework.jdbc.datasource.DataSourceTransactionManager – Initiating transaction rollback
2501 [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager – Initiating transaction rollback
2501 [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager – Rolling back JDBC transaction on Connection [org.apache.derby.impl.jdbc.EmbedConnection40@13320911 (XID = 2827), (SESSIONID = 1), (DATABASE = c:\manoj\mjprojects\database\pumausers), (DRDAID = null) ]
2501 [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager – Rolling back JDBC transaction on Connection [org.apache.derby.impl.jdbc.EmbedConnection40@13320911 (XID = 2827), (SESSIONID = 1), (DATABASE = c:\manoj\mjprojects\database\pumausers), (DRDAID = null) ]
2511

Use SQL to check the database table. Confirm that no record is added.

Step 5: Remove the runtimeexception from the insertMember method and run the test again.

The Spring debug log with show that the transaction is committed. Use SQL to check the database table. Confirm that a record is added to the table.

In summary, Transactions are necessary to maintain ACID properties for data sources. Declarative transactions using Spring makes that task easier.

Reference: Spring and Declarative Transactions from our JCG partner Manoj at the The Khangaonkar Report.

Related Articles :

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

One Response to "Spring Declarative Transactions Example"

  1. Apurav Chauhan says:

    Very nice and simple explanation with source code:

    http://simplespringtutorial.com/springDeclarativeTransactions.html

Leave a Reply


− four = 3



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close