Spring transaction management and Spring transaction management

Source: Internet
Author: User

Spring transaction management and Spring transaction management


Transaction introduction:
Transaction Management is an essential technology in enterprise application development. It is used to ensure data integrity and consistency.
Transactions are a series of actions, which are considered as a separate unit of work. Either all these actions are completed or all of them do not work.
Four key attributes of transactions (ACID)
Atomicity: An atomic operation in a transaction room, which consists of a series of actions. The atomicity of the transaction ensures that the action is either completely completed or completely ineffective.
Consistency: once all transaction actions are completed, the transaction is committed. Data and resources are in a consistent state that satisfies business rules.
Isolation: many transactions may process the same data at the same time. Therefore, each transaction should be isolated from other transactions to prevent data corruption.
Durability: Once a transaction is completed, no matter what system error occurs, its results should not be affected. Generally, the transaction result is written to the persistent storage.

Transaction Management in Spring
As an enterprise application framework, Spring defines an abstraction layer on different Transaction Management APIs. Application developers can use Spring's transaction management mechanism without having to understand the underlying transaction management API.


Spring supports both programming and declarative transaction management.
Programmatic Transaction Management: embedding Transaction Management Code into business methods to control transaction commit and rollback. In programming transactions, additional transaction management code must be included in each business operation.
Declarative Transaction Management: it is easier to use than programmatic transaction management in most cases. It separates the transaction management code from the business method and implements transaction management in a declarative manner. As a cross-cutting concern, transaction management can be modularized using the AOP method. Spring supports declarative transaction management through the Spring AOP framework.

 

Propagation attributes of Spring transactions:

When the transaction method is called by another transaction method, you must specify how the transaction should be propagated. For example, a method may continue to run in an existing transaction or start a new transaction and run it in its own transaction.
The Propagation Behavior of a transaction can be specified by the propagation attribute. Spring defines seven types of propagation behaviors:

Transaction propagation behaviors supported by Spring
Propagation Behavior Description
PROPAGATION_MANDATORY Indicates that the method must be run in the transaction. If the current transaction does not exist, an exception is thrown.
PROPAGATION_NESTED Indicates that if a transaction already exists, this method will run in the nested transaction. Nested transactions can be committed or rolled back independently of the current transaction. If the current transaction does not exist, its behavior is the same as that of PROPAGATION_REQUIRED. Note that the support of various vendors for such promotional activities is different. Check whether they support nested transactions by referring to the Resource Manager documentation.
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 run in the transaction. If the current transaction exists, the current transaction will be suspended during the running of this method. If you use JTATransactionManager, you need to access TransactionManager.
PROPAGATION_REQUIRED Indicates that the current method must run in the transaction. If the current transaction exists, the method runs in the transaction. Otherwise, a new transaction is started.
PROPAGATION_REQUIRED_NEW Indicates that the current method must run in its own transaction. A new transaction will be started. If the current transaction exists, the current transaction will be suspended during the execution of this method. If you use JTATransactionManager, you need to access TransactionManager.
PROPAGATION_SUPPORTS Indicates that the current method does not require the transaction context, but if the current transaction exists, the method will run in this transaction

PROPAGATION_REQUIRED is the default propagation attribute.

 

Problems caused by concurrent transactions
Many unexpected problems may occur when multiple transactions in the same application or different applications are concurrently executed on the same dataset.
The problems caused by concurrent transactions can be divided into the following three categories:
Dirty read: The dirty read occurs when a transaction reads the data rewritten by another transaction but not committed. If the rewrite is rolled back later, the data obtained from the first transaction is invalid.
Non-repeated read: Non-repeated read occurs when a transaction executes the same query twice or more times, but each time it obtains different data. This is usually because another concurrent transaction updates data during two queries.
Phantom read: phantom read is similar to non-repeated read. It occurs when a transaction (T1) reads several rows of data, and another concurrent transaction (T2) inserts some data. In the subsequent query, the first transaction (T1) will find some records that do not exist originally.

----------------------------------------------------- Sample code example ------------------------------------------------------------------------------------

The first is the database table:

Including book (isbn, book_name, price), account (username, balance), book_stock (isbn, stock)

Then the class used:

BookShopDao

1 package com. yl. spring. tx; 2 3 public interface BookShopDao {4 // obtain the unit price of the book according to the book number 5 public int findBookPriceByIsbn (String isbn); 6 // update the inventory of the book, make inventory-1 7 public void updateBookStock (String isbn) corresponding to the book number; 8 // update the user's account balance: Make the balcance-price 9 public void updateUserAccount (String username, int price); 10 11}

BookShopDaoImpl

1 package com. yl. spring. tx; 2 3 import org. springframework. beans. factory. annotation. autowired; 4 import org. springframework. jdbc. core. jdbcTemplate; 5 import org. springframework. stereotype. repository; 6 7 @ Repository ("bookShopDao") 8 public class BookShopDaoImpl implements BookShopDao {9 10 @ Autowired11 private JdbcTemplate; 12 13 @ Override14 public int publish (String isbn) {15 String SQL = "SELECT price FROM book WHERE isbn =? "; 16 17 return JdbcTemplate. queryForObject (SQL, Integer. class, isbn); 18} 19 20 @ Override21 public void updateBookStock (String isbn) {22 // check whether the inventory of the book is sufficient. If not, an exception is thrown 23 String sql2 = "SELECT stock FROM book_stock WHERE isbn =? "; 24 int stock = JdbcTemplate. queryForObject (sql2, Integer. class, isbn); 25 if (stock = 0) {26 throw new BookStockException (" insufficient inventory! "); 27} 28 String SQL =" UPDATE book_stock SET stock = stock-1 WHERE isbn =? "; 29 JdbcTemplate. update (SQL, isbn); 30} 31 32 @ Override33 public void updateUserAccount (String username, int price) {34 // check whether the balance is insufficient. If not, an exception is thrown 35 String sql2 = "SELECT balance FROM account WHERE username =? "; 36 int balance = JdbcTemplate. queryForObject (sql2, Integer. class, username); 37 if (balance <price) {38 throw new UserAccountException (" insufficient balance! "); 39} 40 String SQL =" UPDATE account SET balance = balance -? WHERE username =? "; 41 JdbcTemplate. update (SQL, price, username); 42} 43 44}

BookShopService

1 package com.yl.spring.tx;2 3 public interface BookShopService {4     5     public void purchase(String username, String isbn);6 }

BookShopServiceImpl

1 package com. yl. spring. tx; 2 3 import org. springframework. beans. factory. annotation. autowired; 4 import org. springframework. stereotype. service; 5 import org. springframework. transaction. annotation. isolation; 6 import org. springframework. transaction. annotation. propagation; 7 import org. springframework. transaction. annotation. transactional; 8 9 @ Service ("bookShopService") 10 public class BookShopService Impl implements BookShopService {11 12 @ Autowired13 private BookShopDao bookShopDao; 14 15 16/*** 17*1. add transaction annotation 18 * use propagation to specify the propagation Behavior of the transaction, that is, how to use the transaction when the current transaction method is called by another transaction method. 19 * The default value is REQUIRED, that is, 20 * REQUIRES_NEW: the transaction of the called transaction method is suspended when you use your own transaction. 21*22*2. use isolation to specify the transaction isolation level. The most common value is READ_COMMITTED23 * 3. by default, Spring declarative transactions roll back all runtime exceptions. You can also set the corresponding attributes. Generally, the default value is enough. 24*4. Use readOnly to specify whether the transaction is read-only. Indicates that this transaction only reads data but does not update data, which can help the database engine optimize transactions. If it is really a method to read only the database, you should set readOnly = true25 * 5. Use timeOut to specify the time that the transaction can take before force rollback. 26 */27 @ Transactional (propagation = Propagation. REQUIRES_NEW, 28 isolation = Isolation. READ_COMMITTED, 29 noRollbackFor = {UserAccountException. class}, 30 readOnly = true, timeout = 3) 31 @ Override32 public void purchase (String username, String isbn) {33 // 1. obtain the unit price of a book 34 int price = bookShopDao. findBookPriceByIsbn (isbn); 35 // 2. update the inventory of books 36 bookShopDao. updateBookStock (isbn); 37 // 3. update user balance 38 bookShopDao. updateUserAccount (username, price); 39} 40 41}

BookStockException

 1 package com.yl.spring.tx; 2  3 public class BookStockException extends RuntimeException { 4  5     /** 6      *  7      */ 8     private static final long serialVersionUID = 1L; 9 10     public BookStockException() {11         super();12         // TODO Auto-generated constructor stub13     }14 15     public BookStockException(String arg0, Throwable arg1, boolean arg2,16             boolean arg3) {17         super(arg0, arg1, arg2, arg3);18         // TODO Auto-generated constructor stub19     }20 21     public BookStockException(String arg0, Throwable arg1) {22         super(arg0, arg1);23         // TODO Auto-generated constructor stub24     }25 26     public BookStockException(String arg0) {27         super(arg0);28         // TODO Auto-generated constructor stub29     }30 31     public BookStockException(Throwable arg0) {32         super(arg0);33         // TODO Auto-generated constructor stub34     }35     36 }

UserAccountException

 1 package com.yl.spring.tx; 2  3 public class UserAccountException extends RuntimeException { 4  5     /** 6      *  7      */ 8     private static final long serialVersionUID = 1L; 9 10     public UserAccountException() {11         super();12         // TODO Auto-generated constructor stub13     }14 15     public UserAccountException(String arg0, Throwable arg1, boolean arg2,16             boolean arg3) {17         super(arg0, arg1, arg2, arg3);18         // TODO Auto-generated constructor stub19     }20 21     public UserAccountException(String arg0, Throwable arg1) {22         super(arg0, arg1);23         // TODO Auto-generated constructor stub24     }25 26     public UserAccountException(String arg0) {27         super(arg0);28         // TODO Auto-generated constructor stub29     }30 31     public UserAccountException(Throwable arg0) {32         super(arg0);33         // TODO Auto-generated constructor stub34     }35     36 }

Cashier

1 package com.yl.spring.tx;2 3 import java.util.List;4 5 public interface Cashier {6     7     public void checkout(String username, List<String>isbns);8 }

CashierImpl. CashierImpl. checkout and bookShopService. purchase jointly test the transaction Propagation Behavior

 1 package com.yl.spring.tx; 2  3 import java.util.List; 4  5 import org.springframework.beans.factory.annotation.Autowired; 6 import org.springframework.stereotype.Service; 7 import org.springframework.transaction.annotation.Transactional; 8  9 @Service("cashier")10 public class CashierImpl implements Cashier {11     @Autowired12     private BookShopService bookShopService;13     14     @Transactional15     @Override16     public void checkout(String username, List<String> isbns) {17         for(String isbn : isbns) {18             bookShopService.purchase(username, isbn);19         }20 21     }22 23 }

Test class:

 1 package com.yl.spring.tx; 2  3  4 import java.util.Arrays; 5  6 import org.junit.Test; 7 import org.springframework.context.ApplicationContext; 8 import org.springframework.context.support.ClassPathXmlApplicationContext; 9 10 public class SpringTransitionTest {11     12     private ApplicationContext ctx = null;13     private BookShopDao bookShopDao = null;14     private BookShopService bookShopService = null;15     private Cashier cashier = null;16     17     {18         ctx = new ClassPathXmlApplicationContext("applicationContext.xml");19         bookShopDao = ctx.getBean(BookShopDao.class);20         bookShopService = ctx.getBean(BookShopService.class);21         cashier = ctx.getBean(Cashier.class);22     }23     24     @Test25     public void testBookShopDaoFindPriceByIsbn() {26         System.out.println(bookShopDao.findBookPriceByIsbn("1001"));27     }28 29     @Test30     public void testBookShopDaoUpdateBookStock(){31         bookShopDao.updateBookStock("1001");32     }33     34     @Test35     public void testBookShopDaoUpdateUserAccount(){36         bookShopDao.updateUserAccount("AA", 100);37     }38     @Test39     public void testBookShopService(){40         bookShopService.purchase("AA", "1001");41     }42     43     @Test44     public void testTransactionPropagation(){45         cashier.checkout("AA", Arrays.asList("1001", "1002"));46     }47     48 }

 

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.