The main research in this article is the introduction and examples of Spring transaction isolation level, as follows.
When two transactions operate on records in the same database, what is the impact between them? This brings up the concept of transaction isolation level. The isolation of the database has a lot to do with concurrency control. The isolation level of the database is part of the ACID of the transactional characteristic of the database. ACID, that is, atomicity, consistency, isolation and durability. Spring has four transaction isolation levels: READ_UNCOMMITTED , READ_COMMITTED , REPEATABLE_READ and SERIALIZABLE . Another one is the default isolation level of the database DEFAULT , and MySQL defaults to REPEATABLE_READ .
Let’s take a look at it in detail below.
As the name implies, READ_UNCOMMITTED means that one transaction can read transaction records that another transaction has not been committed. In other words, a transaction can read the data that is still uncommitted by other transactions. This is the weakest isolation level for Spring transactions. See the figure below, Transaction A is turned on and a record is written. At this time, Transaction B reads the data and reads this record, but then Transaction A rolls back. Therefore, the data read by transaction B is not valid (the database is in an invalid state). This situation is called dirty read. In addition to the dirty reading problem, READ_UNCOMMITTED may also have non-repeatable read (not repetitive reading) and phantom read (phantom reading).
The READ_COMMITTED isolation level indicates that a transaction can only read the committed records and cannot read the uncommitted records. In other words, a transaction can only read the committed data, and it can't read the uncommitted data. Therefore, the dirty read situation no longer happens, but other problems may occur. See the picture below.
Between the two reads of transaction A, transaction B modifies that record and commits it. Therefore, the records read before and after transaction A are inconsistent. This problem is called non-repeatable read (cannot be read repeatedly). (The records read inconsistently between the two times, and repeated readings will find problems.)
In addition to the non-repeatable read problem, READ_COMMITTED may also have phantom read problem.
REPEATABLE_READ means that a transaction can read a record from the database multiple times, and the record reads multiple times are the same, the same. This isolation level can avoid the problem of dirty read and non-repeatable read, but the problem of phantom read may occur. As shown in the figure below.
Transaction A reads a series of records from the database twice, during which, transaction B inserts a record and submits it. When transaction A reads the second time, the record that transaction B has just been inserted will be read. During a transaction, a series of records read by transaction A twice is inconsistent, and this problem is called phantom read.
SERIALIZABLE is Spring's strongest isolation level. When a transaction is executed, it will be locked at all levels, such as when read and write, as if the transaction is carried out in a serial way, rather than happening together. This prevents dirty read, non-repeatable read and phantom read, but it will cause performance degradation.
MySQL defaults to REPEATABLE_READ .
Let's look at an example below. Open a transaction in the database mysql, and do not commit. Then another transaction reads the record.
At the beginning, the records in the database are as shown in the figure
Next, open transaction A in the database mysql and insert a record.
The transaction attribute of the service class in the service is configured as READ_UNCOMMITTED .
@Transactional(isolation=Isolation.READ_UNCOMMITTED)public class AccountService {private AccountDAO accountDAO;public AccountDAO getAccountDAO() {return accountDAO;}public void setAccountDAO(AccountDAO accountDAO) {this.accountDAO = accountDAO;}public void transfer(String from, String to, double money) {accountDAO.outMoney(from, money);accountDAO.inMoney(to, money);}public void readAllUser() {List<Account> accounts = accountDAO.getAllUser();for (Account account : accounts) {System.out.println(account);}}}Run the following test class
package com.chris.service;import static org.junit.Assert.*;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class ReadAllUserTest {@Autowired private AccountService accountService;@Test public void test() {accountService.readAllUser();}}The results are as follows:
It can be seen that this transaction reads uncommitted data.
At this time, roll back the transaction A opened in mysql.
mysql> rollback;
Run the program again and the result is
Account [name=Michael, money=1000.0]
Account [name=Jane, money=1000.0]
Account [name=Kate, money=1000.0]
The above is all the content of this article about the introduction to Spring transaction isolation level and the analysis of examples. I hope it will be helpful to everyone. Interested friends can continue to refer to other related topics on this site. If there are any shortcomings, please leave a message to point it out. Thank you friends for your support for this site!