Example of transaction management in spring _java

Source: Internet
Author: User
Tags aop rollback stub throw exception throwable

The example in this article describes transaction management in spring. Share to everyone for your reference. The specific analysis is as follows:

Introduction to Transactions:

Transaction management is an essential technology in enterprise application development to ensure data integrity and consistency

A transaction is a series of actions that are treated as a separate unit of work. These actions are either complete or none of them work.

Four key properties of a transaction (ACID)

① atomicity (atomicity): A business chamber is an atomic operation that consists of a series of actions. The atomicity of the transaction ensures that the action is either complete or completely ineffective
② Consistency (consistency): Once all transaction actions are completed, the transaction is committed. Data and resources are in a consistent state that satisfies business rules
③ Isolation (Isolation): There may be many transactions that handle the same data at the same time, so everything should be isolated from other transactions to prevent data corruption
④ Persistence (Durability): Once a transaction completes, no matter what system error occurs, its results should not be affected. Typically, the result of a transaction is written to the persistent memory

Transaction management in Spring

As an enterprise application framework, spring defines an abstraction layer on top of different transaction management APIs. Instead of having to understand the underlying transaction management APIs, application developers can use spring's transaction management mechanism.

Spring supports both programmatic transaction management and declarative transaction management

Programmatic transaction Management: Embedding transaction management code into business methods to control the commit and rollback of transactions, in which additional transaction management code must be included in each business operation in the programming transaction

Declarative transaction management: In most cases, better than programmatic transaction management. It separates the transaction management code from the business method, and implements transaction management in a declarative manner. Transaction management, as a cross-cutting concern, can be modularized through an AOP approach. Spring supports declarative transaction management through the Spring AOP framework.

Propagation properties for spring transactions:

When a transaction method is called by another transaction method, you must specify how the transaction should propagate. For example, a method might continue to run in an existing transaction, or it might open a new transaction and run in its own transaction.

The propagation behavior of a transaction can be specified by the Propagation property. Spring defines 7 types of propagation behavior:

transaction propagation behavior supported by spring
Propagation behavior Meaning
Propagation_mandatory Indicates that the method must be run in a transaction and an exception is thrown if the current transaction does not exist
propagation_nested Indicates that if a transaction already exists, the method will run in a nested transaction. Nested transactions can be committed individually or rolled back independently of the current transaction. If the current transaction does not exist, the behavior is the same as propagation_required. It is noted that there are differences in the support of the vendors for this kind of communication behavior. You can refer to the Resource Manager's documentation to confirm that they support nested transactions
Propagation_never Indicates that the current method should not run in the transaction context. If a transaction is currently running, an exception is thrown
propagation_not_supported Indicates that the method should not be running in a transaction. If there is a current transaction, the current transaction is suspended while the method is running. If you use Jtatransactionmanager, you need to access TransactionManager
Propagation_required Indicates that the current method must be running in a transaction. If the current transaction exists, the method will run in that transaction. Otherwise, a new transaction is started
Propagation_required_new Indicates that the current method must be running in its own transaction. A new transaction will be started. If there is a current transaction, the current transaction is suspended during the execution of the method. If you use Jtatransactionmanager, you need to access TransactionManager
Propagation_supports Indicates that the current method does not require a transaction context, but if there is a current transaction, then the method will run in this transaction

Where propagation_required is the default propagation property

Problems caused by concurrent transactions

Many unexpected problems can occur when multiple transactions in the same application or in different applications are executed concurrently on the same dataset.

The problems caused by concurrent transactions can be grouped into the following three categories:

① dirty read: Dirty read occurs when one transaction reads data that is overwritten by another transaction but has not yet been committed. If the rewrite is rolled back later, the data obtained by the first transaction is invalid.

② unreadable: Non-repeatable reads occur when a transaction executes the same query two or two times, but each time a different data is obtained. This is usually because another concurrent transaction updated the data during the two query

③: Phantom reads are similar to non repeatable reads. It occurs when a transaction (T1) reads several rows of data, and then another concurrent transaction (T2) inserts some data. In a subsequent query, the first transaction (T1) will find a number of records that would otherwise not exist.

code example

The first is the database table:

Includes book (ISBN, Book_name, Price), account (username, balance), Book_stock (ISBN, stock)

Then the class is used:

Bookshopdao

Copy Code code as follows:

Package com.yl.spring.tx;

Public interface Bookshopdao {
Get the price of a book according to the ISBN
public int FINDBOOKPRICEBYISBN (String ISBN);
Update the inventory of the book, so that the number of the corresponding inventory-1
public void Updatebookstock (String ISBN);
Update the user's account balance: Make the username balcance-price
public void Updateuseraccount (String username, int price);

}

Bookshopdaoimpl

Copy Code code as follows:

Package com.yl.spring.tx;

Import org.springframework.beans.factory.annotation.Autowired;
Import Org.springframework.jdbc.core.JdbcTemplate;
Import Org.springframework.stereotype.Repository;

@Repository ("Bookshopdao")
public class Bookshopdaoimpl implements Bookshopdao {

@Autowired
Private JdbcTemplate JdbcTemplate;

@Override
public int FINDBOOKPRICEBYISBN (String ISBN) {
String sql = "Select Price" WHERE ISBN =? ";

return jdbctemplate.queryforobject (SQL, Integer.class, ISBN);
}

    @Override
    public void Updatebookstock (String ISBN) {
        //Check book inventory is sufficient, if not enough, then throw exception
        String sql2 = " SELECT the Stock from Book_stock WHERE ISBN =? ";
        int stock = Jdbctemplate.queryforobject (Sql2, Integer.class, ISBN);
        if (stock = = 0) {
             throw new Bookstockexception ("Insufficient stock!") ");
       }
        String sql = "UPDATE book_stock SET stock = stock-1 WHERE ISBN =?";
        jdbctemplate.update (sql, ISBN);
   }

@Override
public void Updateuseraccount (String username, int price) {
Check the balance is insufficient, if insufficient, throw an exception
String sql2 = "Select Balance from account WHERE username =?";
int balance = Jdbctemplate.queryforobject (SQL2, Integer.class, username);
if (balance < price) {
throw new Useraccountexception ("Insufficient balance!") ");
}
String sql = "UPDATE account SET balance = balance-?" WHERE username =? ";
Jdbctemplate.update (SQL, price, username);
}

}

Bookshopservice

Copy Code code as follows:
Package com.yl.spring.tx;
Public interface Bookshopservice {
public void Purchase (string username, string ISBN);
}

Bookshopserviceimpl

Copy Code code as follows:

Package com.yl.spring.tx;

Import org.springframework.beans.factory.annotation.Autowired;
Import Org.springframework.stereotype.Service;
Import org.springframework.transaction.annotation.Isolation;
Import org.springframework.transaction.annotation.Propagation;
Import org.springframework.transaction.annotation.Transactional;

@Service ("Bookshopservice")
public class Bookshopserviceimpl implements Bookshopservice {

@Autowired
Private Bookshopdao Bookshopdao;

/**
* 1. Add transaction annotations
* Use propagation to specify the propagation behavior of a transaction, that is, how the transaction is used when the current transaction method is called by another transaction method.
* The default value is required, that is, the transaction using the calling method
* Requires_new: The transaction of the invoked transaction method is suspended using its own transaction.
*
* 2. Use isolation to specify the isolation level of the transaction, the most commonly used value is read_committed
* 3. By default, Spring's declarative transactions roll back all run-time exceptions, or they can be set by corresponding properties. Typically, the default value is available.
* 4. Use readonly to specify whether the transaction is read-only. Indicates that this transaction reads only data but does not update data, which helps the database engine optimize transactions. If it's really a read-only database worthwhile method, you should set Readonly=true
* 5. Use timeout to specify the amount of time a transaction can take before forcing a rollback.
*/
@Transactional (Propagation=propagation.requires_new,
Isolation=isolation.read_committed,
Norollbackfor={useraccountexception.class},
Readonly=true, timeout=3)
@Override
public void Purchase (string username, String ISBN) {
1. Get the price of the book
int price = BOOKSHOPDAO.FINDBOOKPRICEBYISBN (ISBN);
2. Update the inventory of the book
Bookshopdao.updatebookstock (ISBN);
3. Update User balances
Bookshopdao.updateuseraccount (username, price);
}
}

Bookstockexception

Copy Code code as follows:

Package com.yl.spring.tx;
public class Bookstockexception extends RuntimeException {

/**
*
*/
Private static final long serialversionuid = 1L;

Public Bookstockexception () {
Super ();
TODO auto-generated Constructor stub
}

Public Bookstockexception (String arg0, Throwable arg1, Boolean arg2,
Boolean Arg3) {
Super (arg0, Arg1, arg2, ARG3);
TODO auto-generated Constructor stub
}

Public Bookstockexception (String arg0, Throwable arg1) {
Super (arg0, arg1);
TODO auto-generated Constructor stub
}

Public bookstockexception (String arg0) {
Super (ARG0);
TODO auto-generated Constructor stub
}

Public bookstockexception (Throwable arg0) {
Super (ARG0);
TODO auto-generated Constructor stub
}
}

Useraccountexception

Copy Code code as follows:

Package com.yl.spring.tx;
public class Useraccountexception extends RuntimeException {

/**
*
*/
Private static final long serialversionuid = 1L;

Public Useraccountexception () {
Super ();
TODO auto-generated Constructor stub
}

Public Useraccountexception (String arg0, Throwable arg1, Boolean arg2,
Boolean Arg3) {
Super (arg0, Arg1, arg2, ARG3);
TODO auto-generated Constructor stub
}

Public Useraccountexception (String arg0, Throwable arg1) {
Super (arg0, arg1);
TODO auto-generated Constructor stub
}

Public useraccountexception (String arg0) {
Super (ARG0);
TODO auto-generated Constructor stub
}

Public useraccountexception (Throwable arg0) {
Super (ARG0);
TODO auto-generated Constructor stub
}
}

Cashier

Copy Code code as follows:

Package com.yl.spring.tx;
Import java.util.List;
Public interface Cashier {
public void Checkout (String username, LIST<STRING>ISBNS);
}

Cashierimpl. Cashierimpl.checkout and Bookshopservice.purchase jointly tested the propagation behavior of the transaction

Copy Code code as follows:

Package com.yl.spring.tx;

Import java.util.List;

Import org.springframework.beans.factory.annotation.Autowired;
Import Org.springframework.stereotype.Service;
Import org.springframework.transaction.annotation.Transactional;

@Service ("cashier")
public class Cashierimpl implements cashier {
@Autowired
Private Bookshopservice Bookshopservice;

@Transactional
@Override
public void Checkout (String username, list<string> ISBNs) {
for (String Isbn:isbns) {
Bookshopservice.purchase (username, ISBN);
}
}
}

Test class:

Copy Code code as follows:

Package com.yl.spring.tx;

Import Java.util.Arrays;

Import Org.junit.Test;
Import Org.springframework.context.ApplicationContext;
Import Org.springframework.context.support.ClassPathXmlApplicationContext;

public class Springtransitiontest {

Private ApplicationContext CTX = null;
Private Bookshopdao Bookshopdao = null;
Private Bookshopservice bookshopservice = null;
Private cashier cashier = NULL;
{
CTX = new Classpathxmlapplicationcontext ("Applicationcontext.xml");
Bookshopdao = Ctx.getbean (Bookshopdao.class);
Bookshopservice = Ctx.getbean (Bookshopservice.class);
Cashier = Ctx.getbean (Cashier.class);
}

@Test
public void Testbookshopdaofindpricebyisbn () {
System.out.println (BOOKSHOPDAO.FINDBOOKPRICEBYISBN ("1001"));
}

@Test
public void Testbookshopdaoupdatebookstock () {
Bookshopdao.updatebookstock ("1001");
}

@Test
public void Testbookshopdaoupdateuseraccount () {
Bookshopdao.updateuseraccount ("AA", 100);
}
@Test
public void Testbookshopservice () {
Bookshopservice.purchase ("AA", "1001");
}

@Test
public void Testtransactionpropagation () {
Cashier.checkout ("AA", Arrays.aslist ("1001", "1002"));
}
}

I hope this article will help you with your spring programming.

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.