Monday 23 November 2015

Spring @Transactional

DAO Implementation

Let’s implement the DAO for Customer bean, for simplicity we will just have one method to insert record in both customer and address tables.

CustomerDAO.java

package com.journaldev.spring.jdbc.dao;
import com.journaldev.spring.jdbc.model.Customer;
public interface CustomerDAO {
    public void create(Customer customer);
}
CustomerDAOImpl.java


package com.journaldev.spring.jdbc.dao;

import javax.sql.DataSource;

import org.springframework.jdbc.core.JdbcTemplate;

import com.journaldev.spring.jdbc.model.Customer;

public class CustomerDAOImpl implements CustomerDAO {

    private DataSource dataSource;

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    @Override
    public void create(Customer customer) {
        String queryCustomer = "insert into Customer (id, name) values (?,?)";
        String queryAddress = "insert into Address (id, address,country) values (?,?,?)";

        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

        jdbcTemplate.update(queryCustomer, new Object[] { customer.getId(),
                customer.getName() });
        System.out.println("Inserted into Customer Table Successfully");
        jdbcTemplate.update(queryAddress, new Object[] { customer.getId(),
                customer.getAddress().getAddress(),
                customer.getAddress().getCountry() });
        System.out.println("Inserted into Address Table Successfully");
    }

}


Notice that CustomerDAO implementation is not taking care of transaction management. This way we are achieving separation of concerns because sometimes we get DAO implementations from third party and we don’t have control on these classes.

Spring Service with Declarative Transaction Management

Let’s create a Customer Service that will use the CustomerDAO implementation and provide transaction management when inserting records in the customer and address tables in a single method.

CustomerManager.java

package com.journaldev.spring.jdbc.service;
import com.journaldev.spring.jdbc.model.Customer;
public interface CustomerManager {
    public void createCustomer(Customer cust);
}
CustomerManagerImpl.java

package com.journaldev.spring.jdbc.service;
import org.springframework.transaction.annotation.Transactional;
import com.journaldev.spring.jdbc.dao.CustomerDAO;
import com.journaldev.spring.jdbc.model.Customer;
public class CustomerManagerImpl implements CustomerManager {
    private CustomerDAO customerDAO;
    public void setCustomerDAO(CustomerDAO customerDAO) {
        this.customerDAO = customerDAO;
    }
    @Override
    @Transactional
    public void createCustomer(Customer cust) {
        customerDAO.create(cust);
    }
}
If you notice the CustomerManager implementation, it’s just using CustomerDAO implementation to create the customer but provide declarative transaction management through annotating createCustomer() method with @Transactional annotation. That’s all we need to do in our code to get the benefits of Spring transaction management.

@Transactional annotation can be applied over methods as well as whole class. If you want all your methods to have transaction management features, you should annotate your class with this annotation.

The only part remaining is wiring spring beans to get it to work.

Spring Bean Configuration

Create a Spring Bean Configuration file with name as “spring.xml”. We will use this in our test program to wire spring beans and execute our JDBC program to test transaction management.

spring.xml
 

<?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"
    xsi:schemaLocation="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-4.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
    <!-- Enable Annotation based Declarative Transaction Management -->
    <tx:annotation-driven proxy-target-class="true"
        transaction-manager="transactionManager" />
    <!-- Creating TransactionManager Bean, since JDBC we are creating of type
        DataSourceTransactionManager -->
    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>
     
    <!-- MySQL DB DataSource -->
    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/TestDB" />
        <property name="username" value="pankaj" />
        <property name="password" value="pankaj123" />
    </bean>
    <bean id="customerDAO" class="com.journaldev.spring.jdbc.dao.CustomerDAOImpl">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <bean id="customerManager" class="com.journaldev.spring.jdbc.service.CustomerManagerImpl">
        <property name="customerDAO" ref="customerDAO"></property>
    </bean>
</beans>

No comments:

Post a Comment