Spring pure annotation declarative transaction management

affairs

1. What is the business

Transaction is the most basic unit of database operation.

Typical Case: Bank Transfer

2. Four Characteristics of Transactions (ACID)

  • atomicity
  • consistency
  • isolation
  • Persistence

Declarative Transaction Management

  • Annotation-based
  • XML-based configuration file

Declarative transaction management in spring, using AOP principle at the bottom

Transaction Operations (Declarative Transactions)

@Transactional parameter explanation

  • Propagation: Propagation Behavior

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

spread behaviormeaning
PROPAGATION_REQUIREDIf there is no current transaction, a new transaction is created, and if a transaction already exists, it is added to this transaction. This is the most common choice.
PROPAGATION_SUPPORTSSupport the current transaction, if there is no current transaction, it will be executed in a non-transactional mode.
PROPAGATION_MANDATORYIndicates that the method must be run in a transaction, if the current transaction does not exist, an exception will be thrown
PROPAGATION_REQUIRED_NEWIndicates that the current method must run in its own transaction. A new transaction will be started. If there is a current transaction, the current transaction will be suspended during the execution of this method.
PROPAGATION_NOT_SUPPORTEDIndicates that the method should not be run in a transaction. If there is currently a transaction, suspend the current transaction.
PROPAGATION_NEVERIndicates that the current method should not run in a transaction context. Throws an exception if a transaction is currently running
PROPAGATION_NESTEDIf a transaction currently exists, execute within a nested transaction. If there are no current transactions, do something similar to PROPAGATION_REQUIRED.
  • ioslation: transaction isolation
namedescribe
dirty readTransaction A reads the data updated by transaction B, and then B rolls back the operation, so the data read by A is dirty data.
non-repeatable readTransaction A reads the same data multiple times. In , the data is updated and committed, resulting in inconsistent results when transaction A reads the same data multiple times.
hallucinationsSystem administrator A changed the grades of all students in the database from specific scores to ABCDE grades, but system administrator B inserted a record with specific scores at this time. If you change it, it's like hallucination. This is called hallucination.

Non-repeatable reads and phantom reads are easily confused. Non-repeatable reads focus on modification, while phantom reads focus on additions or deletions. To solve the problem of non-repeatable read, you only need to lock the rows that meet the conditions, and to solve the phantom read, you need to lock the table

  • timeout: timeout event

The transaction is committed within a certain period of time, and if it is not committed, it will be rolled back

The default value is -1, the set time is calculated in seconds

  • readOnly: read-only

The default is false, which means that you can query or add, modify, and delete

  • rollbackFor: rollback

Set which exceptions occur for transaction rollback

  • noRollbackFor: do not roll back

Set which exceptions are not rolled back

Related code

1. Configuration file

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
                           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
    <bean id="datasource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/test3"></property>
        <property name="username" value="root"></property>
        <property name="password" value="root"></property>
    </bean>
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="datasource"></property>
    </bean>
<!--    Annotation Scan-->
    <context:component-scan base-package="com.company.Tx"></context:component-scan>
<!--    Create transaction manager-->
    <bean id="Transaction" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="datasource"></property>
    </bean>
    <bean id="sMDao" class="com.company.Tx.Dao.SMDao" abstract="true"></bean>
    <bean id="sMDaoImpl" class="com.company.Tx.Dao.SMDaoImpl" autowire="byType"></bean>
    <bean id="sMService" class="com.company.Tx.Service.SMService" autowire="byType"></bean>
<!--Configure notifications-->
    <tx:advice id="cqw" transaction-manager="Transaction">
        <tx:attributes>
            <tx:method name="playMoney" propagation="REQUIRED" isolation="REPEATABLE_READ"/>
        </tx:attributes>
    </tx:advice>

    <aop:config>
<!--        Configure pointcut-->
        <aop:pointcut id="pt" expression="execution(* com.company.Tx.Service.SMService.*(..))"/>
<!--        Configure Aspects-->
        <aop:advisor advice-ref="cqw" pointcut-ref="pt"></aop:advisor>
    </aop:config>
<!--    Open transaction manager-->
<!--    <tx:annotation-driven transaction-manager="Transaction"></tx:annotation-driven>-->
</beans>

2. Related Dao and Service operation classes

  • SMDao
package com.company.Tx.Dao;

public interface SMDao {
    public void add();
    public void reduce();
}

  • SMDaoImpl
package com.company.Tx.Dao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;


public class SMDaoImpl implements SMDao{
    @Autowired
    JdbcTemplate jdbcTemplate;

    @Override
    public void add() {
        String sqlAdd="update account set money=money-100 where name=?";
        Object[] objects={"cqw"};
        final int update = jdbcTemplate.update(sqlAdd, objects);
        System.out.println("cqw $100 less result::"+update);
    }

    @Override
    public void reduce() {
        String sqlAdd="update account set money=money+100 where name=?";
        Object[] objects={"sm"};
        final int update = jdbcTemplate.update(sqlAdd, objects);
        System.out.println("SM get a result of 100 yuan::"+update);
    }
}

  • SMService
package com.company.Tx.Service;

import com.company.Tx.Dao.SMDao;
public class SMService {

    private SMDao sMDao;

    public void setsMDao(SMDao sMDao) {
        this.sMDao = sMDao;
    }

    public void playMoney(){
        sMDao.add();
        int a=10/0;
        sMDao.reduce();
    }
}

  • TestDemo
    @Test
    public void Test06(){
        ApplicationContext context = new ClassPathXmlApplicationContext("com/company/beanTX.xml");
        final SMService sMService = context.getBean("sMService", SMService.class);
        sMService.playMoney();
    }
  • Result (data rollback, data unchanged)
cqw Result of 100 yuan less::1

java.lang.ArithmeticException: / by zero

	at com.company.Tx.Service.SMService.playMoney(SMService.java:21)

Tags: Database Java Spring

Posted by ev66 on Fri, 03 Jun 2022 00:43:25 +0530