Spring programmatic transaction using TransactionTemplate
All other spring transaction tutorials:
- Spring declarative transaction management XML based
- Spring declarative transaction management Annotation based
- Spring Programmatic Transactions by PlatformTransactionManager
Spring Framework provides two ways to manage programmatic transaction list shown below:
- By using TransactionTemplate
- By using PlatformTransactionManager implementation directly to the code
If you are thinking to do transaction handling programmatically then spring framework recommends use of TransactionTemplate.
Today we will discuss about how to handle spring programmatic transaction using TransactionTemplate
Below are needed to run this example:
- Eclipse ( We are using eclipse Kepler. You could also download eclipse from eclipse.org/downloads)
- MySQL data base (Install MySQL Community Server (GPL) version in your system : MySQL Community Server). We are using version 5.6 ( If you are not sure how to install it please use this link : Install MySQL server )
- Maven 3.0.4
Below are steps:
Step 1. Create table to MySQL database: Please use below script to create table and insert sample data for test to the MySQL database:
DROP TABLE person GO CREATE TABLE person ( id int NOT NULL AUTO_INCREMENT, First_Name varchar(25) NULL, Last_Name varchar(25) NULL, Street_Name varchar(25) NULL, City varchar(25) NULL, State varchar(25) NULL, Country varchar(25) NULL, PRIMARY KEY (id) ) GO
Step 2: Create dynamic web project in eclipse name: SpringDeclarativeTransactionAnnotaion (Please use this link if you are not sure how to create maven project in eclipse: Create maven project in eclipse) . Maven project structure:
Step 3: Create Spring/resources folder inside src/main/resources. Now lets create application-config.xml to complete our XML file configuration. See below copy paste below code in your application-config.xml file
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- DataSource to connect mysql database --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/JavaHonk"></property> <property name="username" value="root"></property> <property name="password" value="admin"></property> </bean> <!-- JdbcTemplate bean to execute query--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- PlatformTransactionManager which are going to drive transaction--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- Instance of transaction template --> <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"> <property name="transactionManager" ref="transactionManager"></property> </bean> <!-- Our main DAO class bean object to execute query --> <bean id="personDAO" class="com.javahonk.dao.PersonDAO"> <property name="jdbcTemplate" ref="jdbcTemplate"></property> <property name="transactionTemplate" ref="transactionTemplate"></property> </bean> </beans>
Step 4: Create three package inside src folder
- com.javahonk
- com.javahonk.dao
- com.javahonk.di.bean
Step 5: Create interface IPersonDAO inside com.javahonk.dao package. This will be our service interface and we will make all method of this interface transactional. Please copy paste below code:
package com.javahonk.dao; import com.javahonk.di.bean.Person; public interface IPersonDAO { int insertUser(Person person); void deletePerson(int personID); void selectAllPerson(); void selectPersonByName(); }
Step 6: Create implementation of above interface and where we will implement all of its method and provide details implementation of transaction. Create class PersonDAO implements IPersonDAO inside com.javahonk.dao package
package com.javahonk.dao; import java.sql.Types; import java.util.Iterator; import java.util.List; import java.util.Map; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallback; import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionTemplate; import com.javahonk.di.bean.Person; public class PersonDAO implements IPersonDAO { private JdbcTemplate jdbcTemplate; private TransactionTemplate transactionTemplate; @Override public int insertUser(final Person person) { //insert statement returns results so we are using //TransactionCallback return transactionTemplate.execute(new TransactionCallback<Integer>() { @Override public Integer doInTransaction(TransactionStatus transactionStatus) { try { String inserQuery = "INSERT INTO person(First_Name," + " Last_Name, Street_Name, City, State, Country)" + " VALUES(?, ?, ?, ?, ?, ?)"; Object[] params = new Object[] { person.getFirstName(), person.getLastName(), person.getStreet(), person.getCity(), person.getState(), person.getCountry() }; int[] types = new int[] { Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR }; int value = jdbcTemplate.update(inserQuery, params, types); System.out.println("\nPerson inserted to the table"); return value; } catch (Exception e) { transactionStatus.setRollbackOnly(); } return 0; } }); } @Override public void deletePerson(final int personID) { //delete statement doesn't returns anything so we are using //TransactionCallbackWithoutResult transactionTemplate.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) { try { String deletePerson = "DELETE FROM person WHERE id =?"; Object[] params = new Object[] { personID }; int[] types = new int[] { Types.VARCHAR }; jdbcTemplate.update(deletePerson, params, types); System.out.println("\nPerson with id 1 deleted from " + "the table\n"); } catch (Exception e) { transactionStatus.setRollbackOnly(); } } }); } @Override public void selectAllPerson() { System.out.println("\nList of person in the table\n"); String selectAllPerson = "SELECT * FROM person"; List<Map<String, Object>> listOfPerson = jdbcTemplate. queryForList(selectAllPerson); for (Iterator<Map<String, Object>> iterator = listOfPerson. iterator(); iterator.hasNext();) { Map<String, Object> map = (Map<String, Object>) iterator.next(); System.out.println(map); } System.out.println(); } @Override public void selectPersonByName() { System.out.println("\nList of person name Java " + "in the table\n"); String selectAllPerson = "SELECT * FROM person where " + "First_Name ='Java'"; List<Map<String, Object>> listOfPerson = jdbcTemplate. queryForList(selectAllPerson); for (Iterator<Map<String, Object>> iterator = listOfPerson. iterator(); iterator.hasNext();) { Map<String, Object> map = (Map<String, Object>) iterator.next(); System.out.println(map); } System.out.println(); } public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } public TransactionTemplate getTransactionTemplate() { return transactionTemplate; } public void setTransactionTemplate(TransactionTemplate transactionTemplate) { this.transactionTemplate = transactionTemplate; } }
Step 7: Now create Person.java bean class which act as business object inside package com.javahonk.di.bean and copy paste below code:
package com.javahonk.di.bean; import java.io.Serializable; public class Person implements Serializable{ private static final long serialVersionUID = 1L; private String FirstName; private String LastName; private String street; private String city; private String state; private String country; public Person(String firstName, String lastName, String street, String city, String state, String country) { super(); FirstName = firstName; LastName = lastName; this.street = street; this.city = city; this.state = state; this.country = country; } public String getFirstName() { return FirstName; } public void setFirstName(String firstName) { FirstName = firstName; } public String getLastName() { return LastName; } public void setLastName(String lastName) { LastName = lastName; } public String getStreet() { return street; } public void setStreet(String street) { this.street = street; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getState() { return state; } public void setState(String state) { this.state = state; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } }
Step 8: Please add below dependencies in pom.xml
<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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.springframework.samples.service.service</groupId> <artifactId>SpringMaven</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <dependencies> <!-- Spring and Transactions --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>3.0.3.RELEASE</version> </dependency> <!-- MySql 5.5 Connector --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.29</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.7.4</version> </dependency> </dependencies> </project>
Step 9: Maven project create logger file automatically but in case it’s not created then create logback.xml inside src\main\resources folder and copy paste below code in it:
<?xml version="1.0" encoding="UTF-8"?> <!-- configuration file for LogBack (slf4J implementation) See here for more details: http://gordondickens.com/wordpress/2013/03/27/sawing-through-the-java-loggers/ --> <configuration scan="true" scanPeriod="30 seconds"> <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator"> <resetJUL>true</resetJUL> </contextListener> <!-- To enable JMX Management --> <jmxConfigurator/> <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%-5level %logger{0} - %msg%n</pattern> </encoder> </appender> <!--<logger name="org.hibernate" level="debug"/> --> <!-- Uncomment and add your logger here: <logger name="org.springframework.samples.service.service" level="debug"/> --> <root level="info"> <appender-ref ref="console"/> </root> </configuration>
Step 10: Our all configuration is completed lastly create main class to test it. Create main class name: TestSpringJDBCTemplate.java inside com.javahonk package and copy paste below content in it:
package com.javahonk; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.javahonk.dao.IPersonDAO; import com.javahonk.di.bean.Person; public class TestSpringJDBCTemplate { public static void main(String[] args) throws Exception { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext( "spring\\application-config.xml"); IPersonDAO personDAO = applicationContext. getBean("personDAO", IPersonDAO.class); Person person = new Person("Java", "Honk", "John st.","NY", "NY", "USA"); //Insert user to the table 3 times: for (int i = 0; i < 3; i++) { personDAO.insertUser(person); } //Delete first person from table personDAO.deletePerson(1); //Select all inserted user from the table personDAO.selectAllPerson(); //Select data from tabel where person //name is "Java" personDAO.selectPersonByName(); applicationContext.close(); } }
Step 11: Our final project structure will look as below:
Step 12: Let’s test it. Right click main class TestSpringJDBCTemplate.java –> Run As –> Java Application. You will see results on the console as below:
Step 13: Data in the table:
- That’s it Spring programmatic transaction using TransactionTemplate completed successfully.
Download source code : Spring programmatic transaction using TransactionTemplate