In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-14 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
The editor today takes you to understand how to understand the transaction management of Spring. The knowledge points in the article are introduced in great detail. Friends who feel helpful can browse the content of the article with the editor, hoping to help more friends who want to solve this problem to find the answer to the problem. Let's follow the editor to learn more about "how to understand the transaction management of Spring".
1. Transaction introduction
Transaction, which generally refers to what is to be done or done. In computer terminology, a program execution unit (unit) that accesses and may update various data items in a database.
Here we will explain with the example of withdrawing money: for example, if you withdraw 1000 yuan from an ATM, there are generally two steps: the first step is to enter the password amount and the bank card deducts 1000 yuan; the second step is to withdraw 1000 yuan from ATM. These two steps must be either performed or not performed. If the bank card deducts 1000 yuan but ATM fails to pay, you will lose 1000 yuan; if the bank card fails to deduct money but ATM pays 1000 yuan, then the bank will lose 1000 yuan.
How to ensure that one of the two steps does not have an exception and the other is successful? Transactions are used to solve such problems. A transaction is a series of actions that together make a complete unit of work, which must be completed, and if one fails, the transaction rolls back to its original state as if nothing had happened. In enterprise application development, transaction management is an essential technology to ensure data integrity and consistency.
2. Four characteristics of transaction (ACID)
①, Atomicity: a transaction 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: once the transaction completes (regardless of success or failure), the system must ensure that the business it models is in a consistent state and does not fail partially. Data in reality should not be corrupted.
③, Isolation: there may be many transactions that process the same data at the same time, so each transaction should be isolated from other transactions to prevent data corruption.
④, Durability: once the transaction is completed, no matter what system error occurs, its results should not be affected, so that it can recover from any system crash. Typically, the results of the transaction are written to persistent memory.
3. The core interface of Spring transaction management
First we create a Java project, and then import the Spring core transaction package
Let's open the core transaction package of Spring and look at the following classes: org.springframework.transaction
The three class files shown above are the transaction management interfaces of Spring. The following figure shows: let's give a brief introduction to these three interfaces.
4. PlatformTransactionManager transaction manager
The interface of Spring transaction manager is org.springframework.transaction.PlatformTransactionManager. As shown in the figure above, Spring does not directly manage transactions. Through this interface, Spring provides corresponding transaction managers for various platforms such as JDBC and Hibernate, that is, to delegate the responsibility of transaction management to transactions of the relevant platform framework provided by persistence mechanisms such as Hibernate or JTA.
Let's go to the PlatformTransactionManager interface and view the source code:
①, TransactionStatus getTransaction (TransactionDefinition definition), the transaction manager manages the transaction by obtaining the "transaction status" through TransactionDefinition.
②, void commit (TransactionStatus status) submit based on status
③, void rollback (TransactionStatus status) rollback based on status
In other words, Spring transaction management provides a consistent programming model for different transaction API, and the specific transaction management mechanism is implemented by the corresponding platforms.
For example, let's import two platforms for transaction management: JDBC and Hibernate
Then we look at the PlatformTransactionManager interface again and find that it has several more implementation classes, as follows:
5. TransactionStatus transaction status
In the above PlatformTransactionManager interface, there are the following methods:
This method returns a TransactionStatus object, and then the program acquires the transaction status based on the returned object, and then operates accordingly.
The contents of the API TransactionStatus are as follows:
This interface describes some transaction processing methods that provide simple ways to control transaction execution and query transaction status, which needs to be applied when rollback or commit.
6. Definition of basic transaction attributes of TransactionDefinition
The transaction manager interface PlatformTransactionManager mentioned above obtains the transaction through the getTransaction (TransactionDefinition definition) method. The parameter in this method is the TransactionDefinition class, which defines some basic transaction properties.
So what are transaction attributes? Transaction attributes can be understood as some basic configuration of the transaction, describing how the transaction strategy is applied to the method. The transaction attribute contains five aspects, as shown in the figure:
The TransactionDefinition API method is as follows:
First, the behavior of communication:
When a transaction method is called by another transaction method, you must specify how the transaction should be propagated.
Spring defines the following seven propagation behaviors. Here is an example of how to propagate transactions between A business and B business:
①, PROPAGATION_REQUIRED: required, must. By default, if A has a transaction, B will use it; if A does not have a transaction, B will create a new transaction.
②, PROPAGATION_SUPPORTS:supports, support. If A has a transaction, B will use it; if A does not have a transaction, B will execute as a non-transaction.
③, PROPAGATION_MANDATORY:mandatory, mandatory. If A has a transaction, B will use it; if A does not have a transaction, B will throw an exception.
④, PROPAGATION_REQUIRES_NEW: requires_new, must be new. If A has a transaction, suspend A's transaction and B creates a new transaction; if A has no transaction, B creates a new transaction.
⑤, PROPAGATION_NOT_SUPPORTED: not_supported, not supported. If A has a transaction, suspend A's transaction and B will execute as a non-transaction; if A has no transaction, B will execute as a non-transaction.
⑥, PROPAGATION_NEVER: never, never. If A has a transaction, B will throw an exception; if A has no transaction, B will execute as a non-transaction.
⑦, PROPAGATION_NESTED: nested, nested. The lower layers of An and B adopt SavePoint mechanism to form nested transactions.
2. Isolation level:
Defines the extent to which one transaction may be affected by other concurrent transactions.
Problems caused by concurrent transactions:
In a typical application, multiple transactions run concurrently, often manipulating the same data to complete their respective tasks. Although concurrency is necessary, it can cause the following problems.
①, dirty read (Dirty reads)-- dirty read occurs when one transaction reads data overwritten by another transaction but not yet committed. If the overwrite is rolled back later, the data obtained by the first transaction is invalid.
②, Nonrepeatable read-non-repeatable reads occur when a transaction executes the same query two or more times, but gets different data each time. This is usually because another concurrent transaction is updated during two queries.
③, Phantom read-Phantom reading is similar to unrepeatable reading. It occurs when one transaction (T1) reads several rows of data, and then another concurrent transaction (T2) inserts some data. In the subsequent query, the first transaction (T1) will find some additional records that do not already exist.
Note: non-repeatable readings focus on modifications, while phantom readings focus on adding or deleting.
In Spring transaction management, the following isolation levels are defined for us:
①, ISOLATION_DEFAULT: use the default isolation level of the backend database
②, ISOLATION_READ_UNCOMMITTED: the lowest isolation level that allows uncommitted data changes to be read, which may result in dirty, phantom or unrepeatable reads
③, ISOLATION_READ_COMMITTED: allow reading of committed data from concurrent transactions to prevent dirty reads, but phantom or unrepeatable reads can still occur
④, ISOLATION_REPEATABLE_READ: the results of multiple reads of the same field are consistent, unless the data is modified by its own transaction, which can prevent dirty reading and non-repeatable reading, but phantom reading can still occur.
⑤, ISOLATION_SERIALIZABLE: the highest isolation level, fully compliant with the ACID isolation level, ensuring that dirty, unrepeatable, and phantom reads are prevented, and the slowest transaction isolation level, as it is usually achieved by fully locking transaction-related database tables
The isolation levels defined above are also expressed in Spring's TransactionDefinition.class as constants-1, 1, 0, 1, 1, 2, and 4, respectively.
For example, the definition of ISOLATION_DEFAULT:
Third, read-only
This is the third feature of a transaction, whether it is a read-only transaction. If the transaction only does this to the back-end database, the database can take advantage of the read-only nature of the transaction to make some specific optimizations. By making the transaction read-only, you can give the database a chance to apply the optimizations it deems appropriate.
IV. Transaction timeout
In order for the application to run well, the transaction cannot run for too long. Because transactions may involve locking to the back-end database, long-term transactions can unnecessarily take up database resources. A transaction timeout is a timer for a transaction, and if the transaction does not finish execution within a certain period of time, it will be automatically rolled back instead of waiting for it to end.
5. Rollback rules
The last aspect of the transaction Pentagon is a set of rules that define which exceptions cause the transaction to roll back and which do not. By default, transactions are rolled back only if they encounter run-time exceptions, but not when they encounter check-type exceptions (this behavior is consistent with EJB's rollback behavior). But you can declare that the transaction rolls back as it encounters a run-time exception when it encounters a specific check-type exception. Similarly, you can declare that a transaction does not roll back when it encounters specific exceptions, even if those exceptions are run-time exceptions.
7. The difference between Spring programmatic transactions and declarative transactions
Programmatic transaction processing: the so-called programmatic transaction refers to the implementation of the transaction by coding, allowing the user to precisely define the boundaries of the transaction in the code. That is, similar to JDBC programming to achieve transaction management. Manage to use TransactionTemplate or directly use the underlying PlatformTransactionManager. For programmatic transaction management, spring recommends using TransactionTemplate.
Declarative transaction processing: management is based on AOP. Its essence is to intercept before and after the method, then create or join a transaction before the target method starts, and commit or roll back the transaction according to execution after the target method is executed. The biggest advantage of declarative transactions is that there is no need to manage transactions programmatically, so there is no need to mix transaction management code with business logic code, and transaction rules can be applied to business logic by making relevant transaction rule declarations in the configuration file (or through @ Transactional annotations).
To put it simply, programmatic transactions invade the business code, but provide more detailed transaction management; while declarative transactions, based on AOP, can not only play the role of transaction management, but also do not affect the specific implementation of the business code.
8. Transfer without transaction
Let's take the transfer as an example. It doesn't have to be a transaction to see how to transfer money. There is the following table account in the database, and the contents are as follows:
There are two users, Tom and Marry. They all have an initial account balance of 10000. At this time, we do the following business: Tom transfers 1000 yuan to Marry. Then this can be broken down into two steps in the program:
The account balance of ① and Tom decreased by 1000 yuan by 10000, leaving a balance of 9000 yuan.
The account balance of ② and Marry increased by 1000 yuan to 11000 yuan.
Either both of the above steps were performed successfully or neither was performed. We control through TransactionTemplate programmatic transactions:
Step 1: create a Java project and import the corresponding jar package
(there are no transactions here, but we don't need so many jar packages. For the following explanation, we import all the jar packages at once.)
Step 2: write the Dao layer
AccountDao interface:
Package com.ys.dao;public interface AccountDao {/ * remittance * @ param outer remitter * @ param money remittance amount * / public void out (String outer,int money); / * * receipt * @ param inner payee * @ param money payment amount * / public void in (String inner,int money);}
AccountDaoImpl interface implementation class
Package com.ys.dao.impl;import org.springframework.jdbc.core.support.JdbcDaoSupport;import com.ys.dao.AccountDao;public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {/ * reduce account amount according to user name * / @ Override public void out (String outer, int money) {this.getJdbcTemplate () .update ("update account set money = money -? Where username =? ", money,outer);} / * increase the account amount according to the user name * / @ Override public void in (String inner, int money) {this.getJdbcTemplate () .update (" update account set money = money +? Where username =? ", money,inner);}} step 3: implement the Service layer
AccountService interface
Package com.ys.service;public interface AccountService {/ * transfer * @ param outer remitter * @ param inner payee * @ param money transaction amount * / public void transfer (String outer,String inner,int money);}
AccountServiceImpl interface implementation class
Package com.ys.service.impl;import com.ys.dao.AccountDao;import com.ys.service.AccountService;public class AccountServiceImpl implements AccountService {private AccountDao accountDao; public void setAccountDao (AccountDao accountDao) {this.accountDao = accountDao;} @ Override public void transfer (String outer, String inner, int money) {accountDao.out (outer, money); accountDao.in (inner, money) }} step 4: Spring global configuration file applicationContext.xml step 5: test public class TransactionTest {@ Test public void testNoTransaction () {ApplicationContext context = new ClassPathXmlApplicationContext ("applicationContext.xml"); AccountService account = (AccountService) context.getBean ("accountService") / / transfer 1000 account.transfer ("Tom", "Marry", 1000) from Tom to Marry;}} step 6: view database table account
The above result is the same as we thought, the Tom account money reduced by 1000 yuan. The amount of the Marry account increased by 1000 yuan.
At this time, the problem arises, for example, it is normal to reduce the money by 1000 yuan in the Tom account. However, an exception occurs when the amount of the Marry account increases, such as a power outage (here we artificially construct an exception whose divisor cannot be 0), as follows:
So at this time, when we execute the test program, it is obvious that there will be an error, so what about the database?
Database account:
We found that the program execution reported an error, but the amount of the database Tom account still decreased by 1000 yuan, but the amount of the Marry account did not increase. This is definitely not allowed in practical application, so how to solve it?
9. Programmatic transaction processing to transfer money (TransactionTemplate)
An exception occurred in the middle of the two steps of the above transfer, but the first step still added the operation in the database. This will not be allowed to happen in practical applications, so we use transactions for management here.
The Dao layer remains the same, we inject the TransactionTemplate template in the Service layer, because the template is used to manage transactions, so the template needs to be injected into the transaction manager DataSourceTransactionManager. In the final analysis, the transaction manager is managed by the underlying JDBC, so we need to inject DataSource into the transaction manager. These steps are as follows:
AccountServiceImpl interface:
Package com.ys.service.impl;import org.springframework.transaction.TransactionStatus;import org.springframework.transaction.support.TransactionCallbackWithoutResult;import org.springframework.transaction.support.TransactionTemplate;import com.ys.dao.AccountDao;import com.ys.service.AccountService;public class AccountServiceImpl implements AccountService {private AccountDao accountDao; private TransactionTemplate transactionTemplate; public void setTransactionTemplate (TransactionTemplate transactionTemplate) {this.transactionTemplate = transactionTemplate;} public void setAccountDao (AccountDao accountDao) {this.accountDao = accountDao } @ Override public void transfer (final String outer,final String inner,final int money) {transactionTemplate.execute (new TransactionCallbackWithoutResult () {@ Override protected void doInTransactionWithoutResult (TransactionStatus arg0) {accountDao.out (outer, money); / / int I = 1 int 0; accountDao.in (inner, money);}});}}
Spring global configuration file applicationContext.xml:
The test file remains unchanged and can be tested twice, the first two operations do not have an exception, and then the database changes normally. An exception occurred in the middle of the second operation and found that the content of the database had not changed.
If you are interested, you can also try the underlying PlatformTransactionManager for transaction management. Here is the main code:
/ / define a TransactionManager of a framework platform, such as JDBC, Hibernate DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager (); dataSourceTransactionManager.setDataSource (this.getJdbcTemplate (). GetDataSource ()); / / set data source DefaultTransactionDefinition transDef = new DefaultTransactionDefinition (); / / define transaction attribute transDef.setPropagationBehavior (DefaultTransactionDefinition.PROPAGATION_REQUIRED); / / set propagation behavior attribute TransactionStatus status = dataSourceTransactionManager.getTransaction (transDef) / / get the transaction status try {/ / Database operation accountDao.out (outer, money); int I = 1canary 0; accountDao.in (inner, money); dataSourceTransactionManager.commit (status); / / commit} catch (Exception e) {dataSourceTransactionManager.rollback (status) / / rollback} 10. Transfer by declarative transaction (xml configuration based on AOP)
The Dao layer and the Service layer remain the same as our original transaction-free implementation. The main reason is that the applicationContext.xml file has changed.
We configure the aop automatic generation agent in the applicationContext.xml file for transaction management:
①, configuration Manager
②, configuration transaction details
③, configure aop
We will not describe the test class here, but also test with and without exceptions, and it is found that the results are consistent with the expected results.
11. Declarative transaction to achieve money transfer (AOP-based annotation configuration)
It is divided into two steps:
①, configure the transaction manager in applicationContext.xml, and hand over the transaction manager to spring
②, add comments to the target class or target method to @ Transactional
First, configure it in the applicationContext.xml file as follows:
Second, add the annotation @ Transactional to the target class or method. If you add on a class, all methods in the class add transactions, and if you add on methods, only that method has transactions.
Package com.ys.service.impl;import javax.annotation.Resource;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;import com.ys.dao.AccountDao;import com.ys.service.AccountService;@Transactional (propagation=Propagation.REQUIRED, isolation = Isolation.DEFAULT) @ Service ("accountService") public class AccountServiceImpl implements AccountService {@ Resource (name= "accountDao") private AccountDao accountDao Public void setAccountDao (AccountDao accountDao) {this.accountDao = accountDao;} @ Override public void transfer (String outer, String inner, int money) {accountDao.out (outer, money); / / int I = 1 int 0; accountDao.in (inner, money);}} Thank you for reading, this is the whole content of "how to understand Spring's transaction Management". Friends who learn to learn, let's get started. I believe that the editor will certainly bring you better quality articles. Thank you for your support to the website!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.