Detailed approach to transaction management in Java Spring Framework _java

Source: Internet
Author: User
Tags aop rollback java spring framework

A database transaction is a sequence of operations that is treated as a single unit of work. These operations are either complete or unsuccessful. Transaction management is an important part of an enterprise-oriented application that ensures data integrity and consistency in an RDBMS. The concept of a transaction can be described in the following description for acid four key properties:

Atomicity: A transaction should be treated as either an entire sequence of operations represented by a single action unit to be successful or unsuccessful.

Consistency: This represents the referential integrity of the database, the consistency of unique primary keys at tables, etc.

Isolation: While there may be many transactions that handle the same dataset, each transaction should be quarantined by others to prevent data corruption.

Persistence: Once the transaction completes, the result of this transaction must be made permanent and cannot be removed from the database due to system failure.

A true RDBMS database system will guarantee all four attributes for each transaction. The simple idea of issuing transactions to use SQL databases is as follows:

Start a transaction using the BEGIN TRANSACTION command.

Use SQL queries to perform various deletions, updates, or inserts.

If all operations are successful, commit is performed, or all operations are rolled back.

The spring Framework provides a layer of abstraction above the different underlying transaction management APIs. Transaction support in spring, designed to provide EJB alternative transactions by adding transactional functionality to the Pojo. Spring supports two kinds of programmatic and declarative transaction management. Required EJB application server, but spring transaction management, without the need for an application server to implement.

Local and global transactions
a local transaction is a single transactional resource that connects like a JDBC, while a global transaction can span a distributed system that is a transaction resource of multiple transactions.

Local transaction management can be useful in a single Web site where the components and resources of an application are located in a centralized computing environment, while transaction management involves only local data management running on a separate machine. Local transactions are more easily implemented.

Global transaction management, which requires a distributed computing environment for all resources distributed across multiple systems. In this case, transaction management requires both local and global levels of work to be done. The execution of a distributed or global transaction on multiple systems requires coordination between the global transaction management system and all local data managers of all relevant systems.

Programming and Declaration
Spring supports two types of transaction management:

    1. Programmatic transaction management: Spring supports two types of transaction management:
    2. Declarative transaction management: This means that your business code is separate from transaction management. You only use annotations or xml-based configuration to manage transactions.

Programmatic transaction Management
the programmatic transaction management approach allows you to manage the transaction with the help of programming source code. This gives a lot of flexibility, but it's hard to maintain.

Before we start, it has at least two database tables, and we can perform various crud operations with the help of a transaction. Let's use the student table, which can be tested in the MySQL database with the following DDL creation:

CREATE TABLE Student (
  ID  int not null auto_increment, NAME VARCHAR is not NULL, age
  INT is not null,
  PR Imary KEY (ID)
);

The second table is marks, and we will keep the students marked as based for many years. Here the SID is the foreign key of the table table.

CREATE TABLE Marks (
  SID int not NULL,
  Marks int is not NULL, year int is not  null
);

Let's use Platformtransactionmanager to implement the transaction directly with the method of programming. To start a new transaction, you need to have an instance of transactiondefinition the appropriate transaction attribute. In this example, we will simply create an instance of Defaulttransactiondefinition using the default transaction attributes.

Once transactiondefinition is created, you can start a transaction by calling the Gettransaction () method, which returns an instance of the Transactionstatus object. The Transactionstatus object helps track the current state of the transaction, and finally, if all goes well, you can commit the transaction using the submitted (Platformtransactionmanager) method, otherwise you can use the rollback () rollback to complete the operation.

Now we are writing the spring JDBC application, which will implement the student and marks table simple operations.
The following is the contents of the data Access object interface file Studentdao.java:

Package Com.yiibai;

Import java.util.List;
Import Javax.sql.DataSource;

Public interface Studentdao {/** * the ' is ' to ' used to ' 
  initialize
  * Database resources ie. conne Ction.
  * * Public
  void Setdatasource (DataSource ds);
  /** * This is the 
  "method" to "used to create
  *" A record in the Student and Marks tables.
  *
  /public void Create (String name, Integer age, Integer marks, integer year);
  /** * This is the 
  "method" to "used to
  " and "All" records from the Student and Marks tables.
  * * Public
  list<studentmarks> liststudents ();
}

The following are the contents of the Studentmarks.java file:

Package Com.yiibai;

public class Studentmarks {
  private Integer age;
  private String name;
  Private Integer ID;
  Private Integer marks;
  Private Integer year;
  Private Integer SID;

  public void Setage (Integer age) {
   this.age = age;
  }
  Public Integer Getage () {return age
   ;
  }

  public void SetName (String name) {
   this.name = name;
  }
  Public String GetName () {return
   name;
  }

  public void SetId (Integer id) {
   this.id = ID;
  }
  Public Integer GetId () {return
   ID;
  }
  public void Setmarks (Integer marks) {
   this.marks = marks;
  }
  Public Integer Getmarks () {return
   marks;
  }

  public void Setyear (Integer year) {
   this.year = year;
  }
  Public Integer getyear () {return year
   ;
  }

  public void Setsid (Integer sid) {
   this.sid = sid;
  }
  Public Integer GetSID () {return
   sid;
  }
}

The following are the contents of the Studentmarksmapper.java file:

Package Com.yiibai;

Import Java.sql.ResultSet;
Import java.sql.SQLException;
Import Org.springframework.jdbc.core.RowMapper;

public class Studentmarksmapper implements rowmapper<studentmarks> {public
  studentmarks Maprow (ResultSet RS , int rownum) throws SQLException {

   Studentmarks studentmarks = new Studentmarks ();

   Studentmarks.setid (Rs.getint ("id"));
   Studentmarks.setname (rs.getstring ("name"));
   Studentmarks.setage (Rs.getint ("Age"));
   Studentmarks.setsid (Rs.getint ("Sid"));
   Studentmarks.setmarks (Rs.getint ("Marks"));
   Studentmarks.setyear (Rs.getint ("Year"));

   Return Studentmarks
  }
}

Here is the definition of the DAO interface Studentdao to implement the class file Studentjdbctemplate.java:

Package Com.yiibai;
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;
  public class Studentjdbctemplate implements Studentdao {private DataSource DataSource;
  Private JdbcTemplate Jdbctemplateobject;

  Private Platformtransactionmanager TransactionManager;
   public void Setdatasource (DataSource DataSource) {this.datasource = DataSource;
  This.jdbctemplateobject = new JdbcTemplate (DataSource); } public void Settransactionmanager (Platformtransactionmanager transactionmanager) {This.transactionmanager = t
  Ransactionmanager; public void Create (String name, Integer age, Integer marks, integer year{Transactiondefinition def = new Defaulttransactiondefinition ();

   Transactionstatus status = Transactionmanager.gettransaction (Def);
     try {String SQL1 = "INSERT into Student (name, age) VALUES (?,?)";

     Jdbctemplateobject.update (SQL1, name, age);
     Get the latest student ID to is used in Marks table String SQL2 = "SELECT Max (ID) from student";

     int sid = Jdbctemplateobject.queryforint (SQL2);
     String SQL3 = "INSERT INTO Marks (SID, Marks, year)" + "VALUES (?,?,?)";

     Jdbctemplateobject.update (SQL3, Sid, Marks, year);
     System.out.println ("Created name =" + Name + ", age =" + age);
   Transactionmanager.commit (status);
     catch (DataAccessException E) {System.out.println ("Error in creating record, rolling back");
     Transactionmanager.rollback (status);
   Throw e;
  } return; Public list<studentmarks> liststudents () {String SQL = ' select * from Student, Marks where Student.id=marks . SiD ";
   List <StudentMarks> studentmarks = Jdbctemplateobject.query (SQL, New Studentmarksmapper ());
  return studentmarks;

 }
}

Now let's move the main application file Mainapp.java, which is as follows:

Package Com.yiibai;
Import java.util.List;
Import Org.springframework.context.ApplicationContext;
Import Org.springframework.context.support.ClassPathXmlApplicationContext;

Import Com.yiibai.StudentJDBCTemplate; public class Mainapp {public static void main (string[] args) {ApplicationContext context = new Classpathxml

   ApplicationContext ("Beans.xml");
   
   Studentjdbctemplate studentjdbctemplate = (studentjdbctemplate) context.getbean ("Studentjdbctemplate");
   SYSTEM.OUT.PRINTLN ("------Records creation--------");
   Studentjdbctemplate.create ("Zara", 11, 99, 2010);
   Studentjdbctemplate.create ("Nuha", 20, 97, 2010);

   Studentjdbctemplate.create ("Ayan", 25, 100, 2011);
   SYSTEM.OUT.PRINTLN ("------Listing all the Records--------");
   list<studentmarks> Studentmarks = studentjdbctemplate.liststudents ();
     for (Studentmarks record:studentmarks) {System.out.print ("ID:" + Record.getid ());
 System.out.print (", Name:" + record.getname ());    System.out.print (", Marks:" + record.getmarks ());
     System.out.print (", Year:" + record.getyear ());
   System.out.println (", Age:" + record.getage ());

 }
  }
}

The following are profiles Beans.xml files:

<?xml version= "1.0" encoding= "UTF-8"?> <beans "xmlns=" 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-3.0.xsd "> <!--initialization for data source--> <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=" password "/> </ Bean> <!--initialization for TransactionManager--> <bean id= "TransactionManager" class= "ORG.SPRINGF" Ramework.jdbc.datasource.DataSourceTransactionManager "> <property name=" DataSource "ref=" DataSource "/> &l T;/bean> <!--Definition for studEntjdbctemplate Bean--> <bean id= "studentjdbctemplate" class= "Com.yiibai.StudentJDBCTemplate" > <prope  
  Rty name= "DataSource" ref= "DataSource"/> <property name= "TransactionManager" ref= "TransactionManager"/>

 </bean> </beans>

After creating the source code and the bean configuration file, let's run the application. If all goes well, this will print the following information:

------Records Creation--------
Created name = Zara, age = one
Created name = Nuha, age = Created
name = Ayan , age =
------Listing All the records--------
id:1, Name:zara, marks:99, year:2010, age:11
id:2 , Name:nuha, marks:97, year:2010, age:20 id:3, Name:ayan, marks:100, year:2011, age:25


Declarative transaction Management
declarative Transaction management methods help you manage configurations, not hard-coded transactions in source code. This means that it can be managed separately from the business code transaction. Manage transactions only with annotations or based on XML configuration. The bean's configuration will specify a method that is transactional. The following are declarative and transaction-related steps:

We use <tx:advice/> tags, which will create we define a pointcut to match all the transactions we want to make, and reference the transaction notification method within it and handle the proposal at the same time.

If the name of a method is already listed in the transaction configuration and then the comments are created, the method is invoked before the transaction begins.

The target method will be executed in a try/catch block.

If the method completes correctly, the AOP recommendation commits the transaction successfully, otherwise the rollback is performed.

Let's take a look at why the above steps work, but before we start, it has at least two database tables, and it is important that we can perform various crud operations with the help of the transaction. Let's use the student table, which can be tested in the MySQL database with the following DDL creation:

CREATE TABLE Student (
  ID  int not null auto_increment, NAME VARCHAR is not NULL, age
  INT is not null,
  PR Imary KEY (ID)
);

The second table is marks, and we will keep the students marked as based for many years. Here SID is the foreign key to table student.

CREATE TABLE Marks (
  SID int not NULL,
  Marks int is not NULL, year int is not  null
);

Also take a look at the examples.
The following is the contents of the data Access object interface file Studentdao.java:

Package Com.yiibai;

Import java.util.List;
Import Javax.sql.DataSource;

Public interface Studentdao {/** * the ' is ' to ' used to ' 
  initialize
  * Database resources ie. conne Ction.
  * * Public
  void Setdatasource (DataSource ds);
  /** * This is the 
  "method" to "used to create
  *" A record in the Student and Marks tables.
  *
  /public void Create (String name, Integer age, Integer marks, integer year);
  /** * This is the 
  "method" to "used to
  " and "All" records from the Student and Marks tables.
  * * Public
  list<studentmarks> liststudents ();
}

The following are the contents of the Studentmarks.java file:

Package Com.yiibai;

public class Studentmarks {
  private Integer age;
  private String name;
  Private Integer ID;
  Private Integer marks;
  Private Integer year;
  Private Integer SID;

  public void Setage (Integer age) {
   this.age = age;
  }
  Public Integer Getage () {return age
   ;
  }

  public void SetName (String name) {
   this.name = name;
  }
  Public String GetName () {return
   name;
  }

  public void SetId (Integer id) {
   this.id = ID;
  }
  Public Integer GetId () {return
   ID;
  }
  public void Setmarks (Integer marks) {
   this.marks = marks;
  }
  Public Integer Getmarks () {return
   marks;
  }

  public void Setyear (Integer year) {
   this.year = year;
  }
  Public Integer getyear () {return year
   ;
  }

  public void Setsid (Integer sid) {
   this.sid = sid;
  }
  Public Integer GetSID () {return
   sid;
  }
}

The following are the contents of the Studentmarksmapper.java file:

Package Com.yiibai;

Import Java.sql.ResultSet;
Import java.sql.SQLException;
Import Org.springframework.jdbc.core.RowMapper;

public class Studentmarksmapper implements rowmapper<studentmarks> {public
  studentmarks Maprow (ResultSet RS , int rownum) throws SQLException {

   Studentmarks studentmarks = new Studentmarks ();

   Studentmarks.setid (Rs.getint ("id"));
   Studentmarks.setname (rs.getstring ("name"));
   Studentmarks.setage (Rs.getint ("Age"));
   Studentmarks.setsid (Rs.getint ("Sid"));
   Studentmarks.setmarks (Rs.getint ("Marks"));
   Studentmarks.setyear (Rs.getint ("Year"));

   Return Studentmarks
  }
}

Here is the definition of the DAO interface Studentdao to implement the class file Studentjdbctemplate.java:

Package Com.yiibai;
Import java.util.List;
Import Javax.sql.DataSource;
Import org.springframework.dao.DataAccessException;

Import Org.springframework.jdbc.core.JdbcTemplate;

  public class Studentjdbctemplate implements studentdao{private JdbcTemplate jdbctemplateobject;
  public void Setdatasource (DataSource DataSource) {this.jdbctemplateobject = new JdbcTemplate (DataSource); public void Create (string name, Integer age, Integer marks, integer year) {try {string SQL1 = ' INSERT INTO
     Student (name, age) VALUES (?,?) ";

     Jdbctemplateobject.update (SQL1, name, age);
     Get the latest student ID to is used in Marks table String SQL2 = "SELECT Max (ID) from student";

     int sid = Jdbctemplateobject.queryforint (SQL2);
     String SQL3 = "INSERT INTO Marks (SID, Marks, year)" + "VALUES (?,?,?)";

     Jdbctemplateobject.update (SQL3, Sid, Marks, year);
     System.out.println ("Created name =" + Name + ", age =" + age); to SImulate the exception.
   throw new RuntimeException ("Simulate Error condition");
     catch (DataAccessException E) {System.out.println ("Error in creating record, rolling back");
   Throw e; } public list<studentmarks> liststudents () {String SQL = ' select * from Student, Marks where student.id=m

   Arks.sid ";
   List <StudentMarks> studentmarks=jdbctemplateobject.query (SQL, New Studentmarksmapper ());
  return studentmarks;

 }
}

Now we move the main application file Mainapp.java, as follows:

Package Com.yiibai;
Import java.util.List;
Import Org.springframework.context.ApplicationContext;

Import Org.springframework.context.support.ClassPathXmlApplicationContext; public class Mainapp {public static void main (string[] args) {ApplicationContext context = new Classpathxml

   ApplicationContext ("Beans.xml");
   
   Studentdao studentjdbctemplate = (Studentdao) context.getbean ("Studentjdbctemplate");
   SYSTEM.OUT.PRINTLN ("------Records creation--------");
   Studentjdbctemplate.create ("Zara", 11, 99, 2010);
   Studentjdbctemplate.create ("Nuha", 20, 97, 2010);

   Studentjdbctemplate.create ("Ayan", 25, 100, 2011);
   SYSTEM.OUT.PRINTLN ("------Listing all the Records--------");
   list<studentmarks> Studentmarks = studentjdbctemplate.liststudents ();
     for (Studentmarks record:studentmarks) {System.out.print ("ID:" + Record.getid ());
     System.out.print (", Name:" + record.getname ());
 System.out.print (", Marks:" + record.getmarks ());    System.out.print (", Year:" + record.getyear ());
   System.out.println (", Age:" + record.getage ());

 }
  }
}

The following are profiles Beans.xml files:

<?xml version= "1.0" encoding= "UTF-8"?> <beans "xmlns=" xmlns: Xsi= "Http://www.w3.org/2001/XMLSchema-instance" 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-3.0.xsd http://www.springframework.org/schema/tx http:// Www.springframework.org/schema/tx/spring-tx-3.0.xsd HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP http:// Www.springframework.org/schema/aop/spring-aop-3.0.xsd "> <!--initialization for data source--> <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=" Cohondob "/> </bean> <tx:advice id=" Txadvice "transaction-manager=" TransactionManager "> <tx:attributes> <tx:method name= "create"/> </tx:attributes> </tx:advice> <aop:conf ig> <aop:pointcut id= "createoperation" expression= "Execution (* com.yiibai.StudentJDBCTemplate.create (..))" /> <aop:advisor advice-ref= "Txadvice" pointcut-ref= "CreateOperation"/> </aop:config> <!--Initi Alization for TransactionManager--> <bean id= "TransactionManager" Org.springframework.jdbc.datasource.DataSourceTransactionManager "> <property name=" DataSource "ref=" DataSource "/> </bean> <!--Definition for studentjdbctemplate Bean--> <bean id=" studentjdbcte Mplate "class=" com.yiibai.StudentJDBCTemplate "> <property name=" dataSource "ref=" DataSource "/> </bea

 N> </beans>

Create the source code and bean configuration file to complete, let's run the application. If all goes well, this will print the following and an exception will be thrown. In this case, the transaction is rolled back and no records are created in the database table.

------Records Creation--------
Created Name = Zara, age = one
Exception in thread "main" Java.lang.RuntimeExceptio N:simulate Error Condition

You can try the above example to remove the exception, in this case, you should commit the transaction, you should see the records in the database.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.