Programmatic
and Declarative transaction management
There are two types of transaction
management in spring:
- Programmatic transaction management: This will give us more flexibility but maintaining this is a bit difficult. In this transaction, we have to manage the transaction with the help of programming.
- Declarative transaction management: It will help to separate the transaction management from the business code. For achieving this we can use annotations or XML based configuration to manage the transactions.
Example to
achieve Programmatic transaction management:-
Below are
the two tables query, which we need to execute in mysql test database , If you
want to change the database name from test to any other then do the change
while configuring the datasource in the xml file.
EMPLOYEE_DATA
Table
CREATE TABLE EMPLOYEE_DATA(
EMP_ID INT NOT NULL AUTO_INCREMENT,
FIRST_NAME VARCHAR(20) NOT NULL,
LAST_NAME VARCHAR(20) NOT NULL,
SALARY DOUBLE NOT NULL,
PRIMARY KEY (EMP_ID) );
ATTENDENCE_DETAILS
Table
CREATE TABLE ATTENDENCE_DETAILS(
EID INT NOT NULL,
NO_OF_LEAVE INT NOT NULL,
NO_OF_WORKING_DAYS INT NOT NULL,JOINING_DATE
DATE NOT NULL );
System Requirements:-
- Eclipse Editor or any other.
- JDK 1.5 or higher(I am using jdk 1.7.0_03)
- Spring jars version 2.5.5.
- Other related jars.
Required
Jars are:-
spring-tx.jar
spring-beans.jar
spring-context.jar
spring-context-support.jar
spring-core.jar
spring-jdbc.jar
spring-orm.jar
commons-logging.jar
commons-collections-3.2.jar
mysql-connector-java-5.0.4-bin.jar
Steps for creating Eclipse java project for implementing spring
transaction management:-
- Create a java project in eclipse and name it as SpringTransactionExample.
- Create a package in the src folder with the name as com.gaurav.springtransaction.dao.
- Create a package in the src folder with the name com.gaurav.springtransaction.bean .
- Create a package in the src folder with the name com.gaurav.springtransaction.mapper.
- Create a package in the src folder with the name com.gaurav.springtransaction.dao.impl.
- Create a package in the src folder with the name com.gaurav.springtransaction.caller.
- Create an XML file and name it as spring-transactionmanagement.xml and place this file in the classpath outside the src folder.
- Place the below available files source codes in the corresponding packages.
- Execute the TestSpringTransactionManagement.java by selecting the option Run as Java Application.
EmployeeDAO.java
package
com.gaurav.springtransaction.dao;
import java.util.Date;
import java.util.List;
import
com.gaurav.springtransaction.bean.EmployeeData;
public interface
EmployeeDAO {
/**
* This method is used to insert a new record
in the employee_data and
* attendence_details tables.
*/
public
void insertNewRow(String firstName, String lastName, Double salary,
Integer
no_of_leave, Integer no_of_working_days, Date joining_date);
/**
* This method is used to retrieve all the
employees records as list
* employee_data and attendence_details tables.
*/
public
List<EmployeeData> retrieveEmployeeList();
}
EmployeeData.java
package
com.gaurav.springtransaction.bean;
import java.util.Date;
public class EmployeeData {
private int empId;
private int eid;
private
String firstName;
private
String lastName;
private
double salary;
private
int noOfLeave;
private
int noOfWorkingDays;
private
Date joiningDate;
/**
* @return the empId
*/
public int getEmpId() {
return
empId;
}
/**
* @param empId
*
the empId to set
*/
public
void setEmpId(int empId) {
this.empId
= empId;
}
/**
* @return the eid
*/
public int getEid() {
return
eid;
}
/**
* @param eid
*
the eid to set
*/
public
void setEid(int eid) {
this.eid
= eid;
}
/**
* @return the firstName
*/
public
String getFirstName() {
return
firstName;
}
/**
* @param firstName
*
the firstName to set
*/
public
void setFirstName(String firstName) {
this.firstName
= firstName;
}
/**
* @return the lastName
*/
public
String getLastName() {
return
lastName;
}
/**
* @param lastName
*
the lastName to set
*/
public
void setLastName(String lastName) {
this.lastName
= lastName;
}
/**
* @return the salary
*/
public
double getSalary() {
return
salary;
}
/**
* @param salary
*
the salary to set
*/
public
void setSalary(double salary) {
this.salary
= salary;
}
/**
* @return the noOfLeave
*/
public
int getNoOfLeave() {
return
noOfLeave;
}
/**
* @param noOfLeave
*
the noOfLeave to set
*/
public
void setNoOfLeave(int noOfLeave) {
this.noOfLeave
= noOfLeave;
}
/**
* @return the noOfWorkingDays
*/
public
int getNoOfWorkingDays() {
return
noOfWorkingDays;
}
/**
* @param noOfWorkingDays
*
the noOfWorkingDays to set
*/
public
void setNoOfWorkingDays(int noOfWorkingDays) {
this.noOfWorkingDays =
noOfWorkingDays;
}
/**
* @return the joiningDate
*/
public
Date getJoiningDate() {
return
joiningDate;
}
/**
* @param joiningDate
*
the joiningDate to set
*/
public
void setJoiningDate(Date joiningDate) {
this.joiningDate
= joiningDate;
}
}
EmployeeAttendenceDetailsMapper.java
package
com.gaurav.springtransaction.mapper;
import java.sql.ResultSet;
import java.sql.SQLException;
import
org.springframework.jdbc.core.RowMapper;
import
com.gaurav.springtransaction.bean.EmployeeData;
public class EmployeeAttendenceDetailsMapper
implements RowMapper {
@Override
public
EmployeeData mapRow(ResultSet rs, int rowNum) throws SQLException
{
EmployeeData
employeeData = new EmployeeData();
employeeData.setEmpId(rs.getInt("EMP_ID"));
employeeData.setFirstName(rs.getString("FIRST_NAME"));
employeeData.setLastName(rs.getString("LAST_NAME"));
employeeData.setSalary(rs.getDouble("SALARY"));
employeeData.setEid(rs.getInt("EID"));
employeeData.setNoOfLeave(rs.getInt("NO_OF_LEAVE"));
employeeData.setNoOfWorkingDays(rs.getInt("NO_OF_WORKING_DAYS"));
employeeData.setJoiningDate(rs.getDate("JOINING_DATE"));
return
employeeData;
}
}
EmployeeDAOImpl.java
package
com.gaurav.springtransaction.dao.impl;
import java.util.Date;
import java.util.List;
import javax.sql.DataSource;
import
org.springframework.dao.DataAccessException;
import
org.springframework.jdbc.core.JdbcTemplate;
import
org.springframework.transaction.PlatformTransactionManager;
import
org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import
org.springframework.transaction.support.DefaultTransactionDefinition;
import
com.gaurav.springtransaction.bean.EmployeeData;
import
com.gaurav.springtransaction.dao.EmployeeDAO;
import
com.gaurav.springtransaction.mapper.EmployeeAttendenceDetailsMapper;
public class
EmployeeDAOImpl implements EmployeeDAO {
private
JdbcTemplate jdbcTemplate;
private
PlatformTransactionManager transactionManager;
/**
* @param DataSource
*
the DataSource to be inject in jdbcTemplate
*/
public
void setDataSource(DataSource ds) {
this.jdbcTemplate
= new JdbcTemplate(ds);
}
/**
* @param transactionManager
*
the transactionManager to set
*/
public
void setTransactionManager(
PlatformTransactionManager
transactionManager) {
this.transactionManager
= transactionManager;
}
@Override
public
void insertNewRow(String firstName, String lastName, Double salary,
Integer
no_of_leave, Integer no_of_working_days, Date joining_date) {
TransactionDefinition
def = new DefaultTransactionDefinition();
TransactionStatus
status = transactionManager.getTransaction(def);
try
{
String
insertQueryForEmployee = "insert into EMPLOYEE_DATA (FIRST_NAME,
LAST_NAME, SALARY) values (?, ?, ?)";
Object[]
queryParameterForEmployeeQuery = { firstName, lastName,
salary
};
jdbcTemplate.update(insertQueryForEmployee,
queryParameterForEmployeeQuery);
/**
* Get the latest employee id from
employee_data table, so that we
* can use it for eid in the
attendence_details table
**/
String
getMaxIdQuery = "select max(EMP_ID) from EMPLOYEE_DATA";
int
eid = jdbcTemplate.queryForInt(getMaxIdQuery);
String
insertQueryForAttendenceDetails = "insert into ATTENDENCE_DETAILS(EID,
NO_OF_LEAVE, NO_OF_WORKING_DAYS, JOINING_DATE) "
+
"values (?, ?, ?, ?)";
Object[]
queryParameterForAttendenceDetailsQuery = { eid,
no_of_leave,
no_of_working_days, joining_date };
jdbcTemplate.update(insertQueryForAttendenceDetails,
queryParameterForAttendenceDetailsQuery);
System.out.println("\n");
System.out.println("Inserted
Query is having First Name = "
+
firstName + ", Last Name = " + lastName
+
", And Joining Date " + joining_date);
transactionManager.commit(status);
}
catch (DataAccessException e) {
System.out
.println("Error
occured during record insertion , so needs to rollback");
transactionManager.rollback(status);
throw
e;
}
return;
}
@Override
public
List<EmployeeData> retrieveEmployeeList() {
String
SQL = "select * from EMPLOYEE_DATA, ATTENDENCE_DETAILS where
EMPLOYEE_DATA.EMP_ID = ATTENDENCE_DETAILS.EID";
@SuppressWarnings("unchecked")
List<EmployeeData>
employeeDataLst = jdbcTemplate.query(SQL,
new
EmployeeAttendenceDetailsMapper());
return
employeeDataLst;
}
}
spring-transactionmanagement.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<!--
mysql data source connection -->
<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/test"
/>
<property
name="username" value="root" />
<property
name="password" value="root" />
</bean>
<!--
Spring TransactionManager Initialization -->
<bean
id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property
name="dataSource" ref="dataSource" />
</bean>
<!--
Provding a definition to EmployeeData for getting data source and spring transaction
manager-->
<bean
id="employeeDAOImplBean" class="com.gaurav.springtransaction.dao.impl.EmployeeDAOImpl">
<property
name="dataSource" ref="dataSource" />
<property
name="transactionManager" ref="transactionManager"
/>
</bean>
</beans>
TestSpringTransactionManagement.java
package
com.gaurav.springtransaction.caller;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;
import
org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContext;
import
com.gaurav.springtransaction.bean.EmployeeData;
import
com.gaurav.springtransaction.dao.impl.EmployeeDAOImpl;
public class TestSpringTransactionManagement
{
public
static void main(String[] args) throws ParseException {
ApplicationContext
context = new ClassPathXmlApplicationContext(
"spring-transactionmanagement.xml");
EmployeeDAOImpl
employeeDAOImplBean
= (EmployeeDAOImpl) context
.getBean("employeeDAOImplBean");
System.out
.println("**********
Inserting the Records in the EmployeeData table ********** ");
int
noOfWorkingDays = 22;
employeeDAOImplBean.insertNewRow("Kumar",
"Gaurav", 70000.00, 5,
(noOfWorkingDays
- 5), (new SimpleDateFormat("yyyy-MM-dd")).parse("2007-05-08"));
employeeDAOImplBean.insertNewRow("Anurag",
"Kumar", 30000.00, 12,
(noOfWorkingDays
- 12), (new SimpleDateFormat("yyyy-MM-dd")).parse("2009-03-27"));
employeeDAOImplBean.insertNewRow("Riya",
"Saxena", 45000.00, 7,
(noOfWorkingDays
- 7), (new SimpleDateFormat("yyyy-MM-dd")).parse("2011-12-15"));
System.out
.println("\n**********
Retrieving all the employee records **********");
List<EmployeeData>
employeeDataLst = employeeDAOImplBean
.retrieveEmployeeList();
for
(EmployeeData employee : employeeDataLst) {
System.out.println("\n");
System.out.print("Employee
ID : " + employee.getEmpId());
System.out.print(",
First Name : " + employee.getFirstName());
System.out.print(",
Last Name : " + employee.getLastName());
System.out.print(",
Salary : " + employee.getSalary());
System.out.print(",
No of Leave : " + employee.getNoOfLeave());
System.out.print(",
No of Working Days : "
+
employee.getNoOfWorkingDays());
System.out.print(",
Joining Date : " + employee.getJoiningDate());
}
}
}
Result:-
Sep 29, 2013 12:22:54 AM
org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing
org.springframework.context.support.ClassPathXmlApplicationContext@16546ef:
display name
[org.springframework.context.support.ClassPathXmlApplicationContext@16546ef];
startup date [Sun Sep 29 00:22:54 IST 2013]; root of context hierarchy
Sep 29, 2013 12:22:54 AM
org.springframework.beans.factory.xml.XmlBeanDefinitionReader
loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource
[spring-transactionmanagement.xml]
Sep 29, 2013 12:22:54 AM org.springframework.context.support.AbstractApplicationContext
obtainFreshBeanFactory
INFO: Bean factory for application context
[org.springframework.context.support.ClassPathXmlApplicationContext@16546ef]:
org.springframework.beans.factory.support.DefaultListableBeanFactory@a353ed
Sep 29, 2013 12:22:54 AM
org.springframework.beans.factory.support.DefaultListableBeanFactory
preInstantiateSingletons
INFO: Pre-instantiating singletons in
org.springframework.beans.factory.support.DefaultListableBeanFactory@a353ed:
defining beans [dataSource,transactionManager,employeeDAOImplBean]; root of
factory hierarchy
Sep 29, 2013 12:22:54 AM
org.springframework.jdbc.datasource.DriverManagerDataSource setDriverClassName
INFO: Loaded JDBC driver: com.mysql.jdbc.Driver
********** Inserting the Records in the EmployeeData table **********
Inserted Query is having First Name = Kumar, Last Name = Gaurav, And
Joining Date Tue May 08 00:00:00 IST 2007
Inserted Query is having First Name = Anurag, Last Name = Kumar, And
Joining Date Fri Mar 27 00:00:00 IST 2009
Inserted Query is having First Name = Riya, Last Name = Sexena, And
Joining Date Thu Dec 15 00:00:00 IST 2011
********** Retrieving all the employee records **********
Employee ID : 1, First Name : Kumar, Last Name : Gaurav, Salary : 70000.0,
No of Leave : 5, No of Working Days : 17, Joining Date : 2007-05-08
Employee ID : 2, First Name : Anurag, Last Name : Kumar, Salary : 30000.0,
No of Leave : 12, No of Working Days : 10, Joining Date : 2009-03-27
Employee
ID : 3, First Name : Riya, Last Name : Saxena, Salary : 45000.0, No of Leave :
7, No of Working Days : 15, Joining Date : 2011-12-15
Below is
the data availability status in the corresponding tables after successful
program execution:-
EMPLOYEE_DATA
ATTENDENCE_DETAILS
No comments:
Post a Comment