Spring transaction management

Posted by tillaart36 on Mon, 07 Mar 2022 15:11:29 +0100

1, Basic concepts of transaction
1. What is a transaction
(1) Transaction is the most basic unit of database operation. Logically, a group of operations either succeed or fail if one fails
(2) Typical scenario: bank transfer
2. Transactions have four characteristics (ACID)
(1) Atomicity: to succeed, to fail, to fail
(2) Consistency: the total amount remains unchanged before and after the operation
(3) Isolation: no impact between multiple transactions
(4) Persistence: the data will change permanently after the transaction is committed successfully

2, Build a transaction operation environment
Environment: WEB layer; Service layer (business operation); Business layer (Dao, no write operation).
Create implementation methods in Dao layer and methods in Service layer, but call Dao layer methods.
For example: zhangsan's money plus 1, lisi's money minus 1:
1. Create database tables and add records
2. Create Service, build Dao, and complete object creation and injection relationship
(1) Service is injected into Dao, JdbcTemplate is injected into Dao, and DataSource is injected into JdbcTemplate

  • Connection pool in configuration file
    <!--Component scan-->
    <context:component-scan base-package="com.at"></context:component-scan>


    <!--Database connection pool-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
        <property name="name" value="jdbc:mysql://localhost:3306/demo1?useUnicode=true&characterEncoding=utf-8"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    </bean>
  • Create UserDao interface in dao and implement UserDaoImpl of UserDao
public interface UserDao {
}

@Repository
public class UserDaoImpl implements UserDao{
    @Autowired
    private JdbcTemplate jdbcTemplate;
}
@Service
public class UserService {
    //Injection dao
    @Autowired
    private UserDao userDao;
}

In the configuration file

    <!--JdbcTemplate object-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!--injection dataSource-->
        <property name="dataSource" ref="dataSource"></property>
    </bean>

3. Create two methods in dao: add and sub methods, and create methods in service (add and sub at the same time)

public interface UserDao {
    public void add();
    public void sub();
}
@Repository
public class UserDaoImpl implements UserDao{
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public void add() {
        String sql = "update t_account set money=money+? where username=?";
        jdbcTemplate.update(sql,1,"zhangsan");
    }

    @Override
    public void sub() {
        String sql = "update t_account set money=money-? where username=?";
        jdbcTemplate.update(sql,1,"lisi");
    }
}
@Service
public class UserService {
    //Injection dao
    @Autowired
    private UserDao userDao;
    public void addSub() {
        userDao.add();
        userDao.sub();
    }
}

4. There is no problem with the normal execution of the above code, but if the code is abnormal during the execution of the project, it will cause problems

For example:

    public void addSub() {
        userDao.add();
        
        //Suppose a failure occurs here
        . . . . . . 
        
        userDao.sub();
    }

In userdao If there is a failure after add(), then userdao Sub () will not be executed, so add and sub cannot be executed at the same time
(1) Solution

  • Use transaction resolution

(2) Transaction operation process

    public void addSub() {
        try {
            //1. Start transaction

            //2. Conduct business operations

            userDao.add();

            //Suppose a failure occurs here
            . . . . . . 

            userDao.sub();

            //3. No exception occurred and the transaction was committed
        } catch (Exception e) {
            //4. If an exception occurs, the transaction is rolled back
        }
    }

3, Introduction to Spring transaction management
1. Transactions are generally added to the Service layer (business logic layer) in the three-tier structure of Java EE

2. Transaction management in Spring
(1) There are two kinds: programmed transaction management and declarative transaction management. (mostly declarative)

Programming:

    public void addSub() {
        try {
            //1. Start transaction

            //2. Conduct business operations

            userDao.add();

            //Suppose a failure occurs here
            . . . . . . 

            userDao.sub();

            //3. No exception occurred and the transaction was committed
        } catch (Exception e) {
            //4. If an exception occurs, the transaction is rolled back
        }
    }

3. Declarative transaction management
(1) Annotation based approach (annotation based approach is used most of the time)
(2) xml based configuration file mode

4. Carry out declarative transaction management in Spring, and the underlying layer uses AOP principle

5. Spring Transaction Management API
(1) An interface is provided to represent the transaction manager. This interface provides different implementation classes for different frameworks

Interface: PlatformTransactionManager
The JDBC implementation class is DataSourceTransactionManager

4, Declarative transaction management based on annotation
1. Configure transaction manager in Spring: configuration file

    <!--Database connection pool-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
        <property name="name" value="jdbc:mysql://localhost:3306/demo1?useUnicode=true&characterEncoding=utf-8"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    </bean>

    <!--Create transaction manager-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--Injection data source-->
        <property name="dataSource" ref="dataSource"></property>
    </bean>

2. In the Spring configuration file, open the transaction annotation
(1) Introduce namespace tx into Spring configuration file

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
                            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

(2) Open transaction annotation

    <!--Open transaction annotation-->
    <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>

3. Add transaction annotation on the Service class (get the method in the Service class)
(1) @ Transactional, this annotation can be added to classes or methods
(2) If you add this annotation to the class, all the methods in the class will add transactions
(3) If you add this annotation to the method, add transactions for the method

@Service
@Transactional
public class UserService {

In this way, when an exception occurs, it can be handled automatically and rolled back

5, Declarative transaction management parameter configuration
1. Add the annotation @ Transactional on the service class, in which transaction related parameters can be configured

  • Propagation: transaction propagation behavior
    (1) Multiple transaction methods are called directly. How are transactions managed in this process
    (transaction method: the operation of changing database table data, such as query is not a transaction method)
    For example, when a method with transaction behavior calls a method without transaction behavior, when a method with transaction behavior calls a method with transaction behavior, and when a method without transaction behavior calls a method with transaction behavior, how to deal with it.

Common:
REQUIRED: if a transaction is running, the current method will run in the transaction. Otherwise, a new transaction will be started and run in its own transaction
REQUIRED_NEW: the current method must start a new transaction and run within its own transaction. If a transaction is running, it should be suspended

@Service
@Transactional(propagation = Propagation.REQUIRED)
public class UserService {
  • Isolation: transaction isolation level
    (1) Transactions have a feature of isolation: there is no impact between multi transaction operations. Not considering isolation creates many problems.
    (2) There are three reading problems: dirty reading, non repeatable reading and virtual (illusory) reading
    (3) Dirty read: between multiple transactions, one uncommitted transaction reads data from another uncommitted transaction
    (4) Non repeatable reading: one uncommitted transaction reads the modified data of another committed transaction
    (5) Virtual (phantom) read: an uncommitted transaction reads and adds data to another committed transaction
    (6) The above problems can be solved by setting the transaction isolation level
Dirty readingNon repeatable readingUnreal reading
READ UNCOMMITTEDhavehavehave
READ COMMITTEDnothinghavehave
REPEATABLE READnothingnothinghave
SERIALIZABLEnothingnothingnothing
@Service
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ)
public class UserService {

(mysql defaults to REPEATABLE READ)

  • Timeout: timeout
  • readOnly: read only
  • Rollback for: rollback
  • noRollbackFor: no rollback

Topics: Java Spring xml