Introduction to Spring framework -- Spring transaction

catalogue

Chapter 5: Spring transactions

5.1 transaction management in spring

5.1.1 review of affairs

5.1.2 transaction management in spring

5.2 API of spring transaction management

5.2.1 transaction manager

5.2.2 transaction definition interface

5.2.3 timing of spring committing and rolling back transactions

5.2.4 summarizing Spring transactions

5.3 instance (Spring instance is not used yet)

5.3.1 creating database tables

5.3.2 add dependencies to Maven's pom.xml file

5.3.3 create entity class

5.3.4 define dao interface and corresponding mapper file

5.3.5 defining exception classes

5.3.6 define service interface and its implementation class

5.3.7 MyBatis configuration file

5.3.8 Spring configuration file

5.3.9 testing

5.4 managing transactions using Spring's transaction annotations

5.4.1 @Transactional annotation

5.4.2 declaration transaction manager

5.4.3   Enable annotation driven

5.4.4   Add transaction attributes to the public method of the business layer

5.4.5 test code

5.4.6    summary

5.5 AOP configuration management transactions using AspectJ

5.5.1 adding Aspectj dependency

5.5.2 declaration transaction manager

5.5.3 configuring transaction notifications

5.5.4 configuration of intensifier

5.5.6 test code

Chapter 5: Spring transactions

5.1 transaction management in spring

5.1.1 review of affairs

    When integrating mysql, the transaction is proposed. Transaction refers to a set of sql statements. There are multiple sql statements in the set, which may be insert, update, select or delete. We hope that these multiple sql statements succeed or fail at the same time. The execution results of these sql statements are consistent and executed as a whole.

    When the operation involves multiple tables or multiple sql statements, second, we need to ensure that these statements are successful to complete my function or fail to ensure that the operation meets the requirements.

    How JDBC accesses the database and handles transactions:

        Connection conn;   conn.commit();   conn.rollback();

    How mybatis accesses the database and handles transactions:

        SqlSession.commit();   SqlSession.rollback();

    hibernate accesses the database and handles transactions in the following ways:

        Session.commit();   Session.rollback();

    It can be seen from the above that different database access technologies have different objects and methods to deal with transactions. Therefore, it is necessary to understand the principle of transactions used by different database access technologies; We also need to master the transaction processing logic and various methods of processing transactions in a variety of databases. That is, a variety of database access technologies have different transaction processing mechanisms, objects and methods.

5.1.2 transaction management in spring

    In the first mock exam, Spring provides a unified model for transaction processing, which can accomplish transaction processing of different database access technologies by unified steps. It is equivalent to using the transaction processing mechanism of spring, which can complete both the transaction processing of mybatis accessing the database and the transaction processing of hibernate accessing the database.

    Transaction was originally a concept in the database, at the Dao layer. However, in general, transactions need to be promoted to the business layer, that is, the Service layer. This is done in order to be able to use the characteristics of transactions to manage specific businesses. In Spring, transaction management can be implemented in the following two ways:

         ① Manage transactions using Spring's transaction annotations

         ② Manage transactions using AspectJ's AOP configuration  

5.2 API of spring transaction management

    The steps of Spring's transaction processing model are fixed. Just provide the information used by transactions to Spring.

5.2.1 transaction manager

    Spring commits and rolls back transactions internally, using the transaction manager object instead of completing commit and rollback.

    The transaction manager is an interface and its many implementation classes.

         PlatformTransactionManager interface object: mainly used to complete transaction submission, rollback, and acquisition

       Status information.

         The PlatformTransactionManager interface has two common implementation classes:

                ① Data source transaction manager: used when using JDBC or MyBatis for database operations.

                ② Hibernate transaction manager: used when using hibernate to persist data.

    Usage: you need to tell spring what kind of database access count you use, declare the transaction manager implementation class corresponding to the database access count, and use the < bean > declaration in the spring configuration file.

        <bean id="xxx" class="...DataSourceTransactionManager">

5.2.2 transaction definition interface

    The transaction definition interface, TransactionDefinition, defines three types of constants related to transaction description: transaction isolation level, transaction propagation behavior, transaction default timeout, and their operations.

    1. Transaction ISOLATION level: there are 4 values. These constants are based on ISOLATION_ At the beginning, it is like ISOLATION_XXX.

        ① DEFAULT: the DEFAULT transaction isolation level of DB is adopted. MySql defaults to REPEATABLE_READ; Oracle

          The default is READ_COMMITTED.

        ②READ_UNCOMMITTED: read uncommitted. No concurrency issues were resolved.

        ③READ_COMMITTED: read committed. Solve dirty reading, there are non repeatable reading and unreal reading.

        ④REPEATABLE_READ: repeatable. Solve dirty reading, non repeatable reading and phantom reading.

        ⑤ SERIALIZABLE: serialization. There is no concurrency problem.

    2. Transaction PROPAGATION behavior: refers to the maintenance of transactions during execution when methods in different transactions call each other. For example, when the method doSome() in transaction A calls the method doOther() in transaction B, the maintenance of the transaction during the call execution is called transaction PROPAGATION behavior. Transaction PROPAGATION behavior is added to the method. Transaction PROPAGATION behavior constants are based on PROPAGATION_ Start with the shape of promotion_ XXX.

        ①PROPAGATION_REQUIRED: the specified method must be executed within a transaction. If there is a transaction, join it

          To the current transaction; If there is no current transaction, a new transaction is created. This communication behavior is the most common choice and

          Spring default transaction propagation behavior.

        ②PROPAGATION_SUPPORTS: the specified method supports the current transaction, but if there is no current transaction, you can also use the

          Non transactional execution.

        ③PROPAGATION_REQUIRES_NEW: always create a new transaction. If there is a current transaction, the current transaction will be deleted

          The transaction is suspended until the new transaction is completed.

        ④PROPAGATION_MANDATORY

        ⑤PROPAGATION_NESTED

        ⑥PROPAGATION_NEVER

        ⑦PROPAGATION_NOT_SUPPORTED

    3. Transaction timeout: constant TIMEOUT_DEFAULT defines the default timeout period at the bottom of the transaction and the execution time of sql statements. Indicates the longest execution time of a method. If the execution time of the method exceeds the time, the transaction will be rolled back. The unit is seconds, integer value, and the default is - 1.

5.2.3 timing of spring committing and rolling back transactions

    ① When your business method is executed successfully and no exception is thrown, spring will automatically commit the transaction after the method is executed. (transaction manager commit)

    ② When your business method throws a runtime exception or ERROR, spring executes rollback (transaction manager rollback). Definition of runtime exception: RuntimeException and its subclasses, such as NullPointException and NumberFormatException.

    ③ Commit a transaction when your business method throws a non runtime exception, mainly a checked exception (compile time exception). Checked exception: exceptions that must be handled in code, such as IOException and SQLException.

5.2.4 summarizing Spring transactions

    1. It is the transaction manager and its implementation classes that manage transactions.

    The first mock exam of 2.Spring is a unified model.

        ① Specify the transaction manager implementation class to use, using < bean >;

        ② Specify which classes and methods need to be added to the transaction function;

        ③ Specify the isolation level, propagation behavior, timeout required by the method.

5.3 instance (Spring instance is not used yet)

5.3.1 creating database tables

    1. Sales table

    2.goods list

        Add data manually:

5.3.2 add dependencies to Maven's pom.xml file

<dependencies>
    <!--unit testing -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
        <scope>test</scope>
    </dependency>
    <!--spring core ioc-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.5.RELEASE</version>
    </dependency>
    <!--do spring Used in transactions-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>5.2.5.RELEASE</version>
    </dependency>
    <!--do spring Used in transactions-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.2.5.RELEASE</version>
    </dependency>
    <!--mybatis rely on-->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.1</version>
    </dependency>
    <!--mybatis and spring Integrated dependencies-->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>1.3.1</version>
    </dependency>
    <!--mysql drive-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.9</version>
    </dependency>
    <!--Alibaba's database connection pool-->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.12</version>
    </dependency>
</dependencies>

5.3.3 create entity class

package com.bjpowernode.domain;

public class Goods {
    private Integer id;
    private String name;
    private Integer amount;
    private Float price;

    public Goods() {
    }

    public Goods(Integer id, String name, Integer amount, Float price) {
        this.id = id;
        this.name = name;
        this.amount = amount;
        this.price = price;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAmount() {
        return amount;
    }

    public void setAmount(Integer amount) {
        this.amount = amount;
    }

    public Float getPrice() {
        return price;
    }

    public void setPrice(Float price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Goods{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", amount=" + amount +
                ", price=" + price +
                '}';
    }
}
package com.bjpowernode.domain;

public class Goods {
    private Integer id;
    private String name;
    private Integer amount;
    private Float price;

    public Goods() {
    }

    public Goods(Integer id, String name, Integer amount, Float price) {
        this.id = id;
        this.name = name;
        this.amount = amount;
        this.price = price;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAmount() {
        return amount;
    }

    public void setAmount(Integer amount) {
        this.amount = amount;
    }

    public Float getPrice() {
        return price;
    }

    public void setPrice(Float price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Goods{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", amount=" + amount +
                ", price=" + price +
                '}';
    }
}

5.3.4 define dao interface and corresponding mapper file

package com.bjpowernode.dao;

import com.bjpowernode.domain.Goods;

public interface GoodsDao {
    //Update inventory
    //goods indicates the product information, id and purchase quantity purchased by the user this time
    int updateGoods(Goods good);

    //Query commodity information
    Goods selectGoods(Integer id);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bjpowernode.dao.GoodsDao">
    <select id="selectGoods" resultType="com.bjpowernode.domain.Goods">
        select id,name,amount,price from goods where id=#{gid}
    </select>
    <update id="updateGoods">
        update goods set amount = amount - #{amount} where id=#{id}
    </update>
</mapper>
package com.bjpowernode.dao;

import com.bjpowernode.domain.Sale;

public interface SaleDao {
    //Add sales record
    int insertSale(Sale sale);

}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bjpowernode.dao.SaleDao">
    <insert id="insertSale">
        insert into sale(gid,nums) values (#{gid},#{nums})
    </insert>
</mapper>

5.3.5 defining exception classes

    Define the exception class notenoughexception that may be thrown by the service layer (the number of goods may not be enough).

package com.bjpowernode.excep;

//Custom runtime exception
public class NotEnoughException extends RuntimeException {
    public NotEnoughException() {
        super();
    }

    public NotEnoughException(String message) {
        super(message);
    }
}

5.3.6 define service interface and its implementation class

package com.bjpowernode.service;

public interface BuyGoodsService {
    //Method of purchasing goods, goodsId: number of purchased goods, Num: quantity purchased
    void buy(Integer goodsId,Integer nums);
}
package com.bjpowernode.service.impl;

import com.bjpowernode.dao.GoodsDao;
import com.bjpowernode.dao.SaleDao;
import com.bjpowernode.domain.Goods;
import com.bjpowernode.domain.Sale;
import com.bjpowernode.excep.NotEnoughException;
import com.bjpowernode.service.BuyGoodsService;

public class BuyGoodsServiceImpl implements BuyGoodsService {

    private SaleDao saleDao;
    private GoodsDao goodsDao;

    public void setSaleDao(SaleDao saleDao) {
        this.saleDao = saleDao;
    }

    public void setGoodsDao(GoodsDao goodsDao) {
        this.goodsDao = goodsDao;
    }

    @Override
    public void buy(Integer goodsId, Integer nums) {
        System.out.println("===buy Start of method===");
        //Record sales information and add records to the sales table
        Sale sale = new Sale();
        sale.setGid(goodsId);
        sale.setNums(nums);
        saleDao.insertSale(sale);
        //Update inventory
        Goods goods = goodsDao.selectGoods(goodsId);
        if(goods == null){
            //Item does not exist
            throw new NullPointerException("The number is:" + goodsId + ",Item does not exist");
        }else if(goods.getAmount() < nums){
            //Insufficient inventory of purchased goods
            throw new NotEnoughException("The number is:" + goodsId + ",Insufficient inventory of goods");
        }
        //Modify inventory
        Goods buyGoods = new Goods();
        buyGoods.setId(goodsId);
        buyGoods.setAmount(nums);
        goodsDao.updateGoods(buyGoods);
        System.out.println("===buy Method completion===");
    }
}

5.3.7 MyBatis configuration file

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <!--Set alias-->
    <typeAliases>
        <!--name: Package name of entity class-->
        <package name="com.bjpowernode.domain"/>
    </typeAliases>

    <!--sql mapper(sql Location of the mapping file)-->
    <mappers>
        <!--
            name: Is the package name. All the mapper.xml It can be loaded at one time
        -->
        <package name="com.bjpowernode.dao"/>
    </mappers>
</configuration>

5.3.8 Spring 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: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/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!--
        Write the configuration information of the database in an independent file to modify the configuration content of the database
        spring know jdbc.properties File location
    -->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!--Declare data source DataSource,The function is to connect to the database-->
    <bean id="myDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <!--set injection DruidDataSource Provides information about linked databases-->
        <!--
            Use the data in the property configuration file, syntax ${key}
        -->
        <property name="url" value="${jdbc.url}"/><!--setUrl()-->
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.passwd}"/>
        <property name="maxActive" value="${jdbc.max}"/>
    </bean>

    <!--statement mybatis Provided in SqlSessionFactoryBean Class, which is created internally SqlSessionFactory of
        SqlSessionFactory sqlSessionFactory = new ...
    -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--set Injection, assigning the database connection pool to dataSource attribute-->
        <property name="dataSource" ref="myDataSource"/>
        <!--mybatis Location of the master profile
            configLocation Property is Resource Type, read configuration file
            Its assignment, using value,Specify the path to the file, using classpath: Indicates the location of the file
        -->
        <property name="configLocation" value="classpath:mybatis.xml"/>
    </bean>

    <!--establish dao Objects, using SqlSession of getMapper(StudentDao.class)
        MapperScannerConfigurer: Call internally getMapper()Generate each dao Proxy object for the interface.
    -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--appoint SqlSessionFactory Object id-->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <!--Specify the package name, which is dao Package name of the interface
            MapperScannerConfigurer It will scan all interfaces in the package and execute each interface
            once getMapper()Method to get the of each interface dao object
            Created dao Object into spring In the container.  dao The default name of an object is the lowercase initial of the interface name
        -->
        <property name="basePackage" value="com.bjpowernode.dao"/><!--Multiple packages can be used,Comma separated-->
    </bean>

    <!--statement service object-->
    <bean id="buyGoodsService" class="com.bjpowernode.service.impl.BuyGoodsServiceImpl">
        <property name="saleDao" ref="saleDao"/>
        <property name="goodsDao" ref="goodsDao"/>
    </bean>
</beans>

5.3.9 testing

public class MyTest {

    @Test
    public void test01(){
        String config = "applicationContext.xml";
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(config);
        //Get service from container
        BuyGoodsService service = (BuyGoodsService) applicationContext.getBean("buyGoodsService");

        //Call method
        service.buy(1001,20);

    }
}

5.4 managing transactions using Spring's transaction annotations

5.4.1 @Transactional annotation

    Through @ Transactional annotation, transactions can be woven into corresponding public methods to realize transaction management. The spring framework uses aop to implement the function of adding transactions to business methods, and uses @ Transactional annotation to add transactions@ The Transactional annotation is the spring framework's own annotation, which is placed above the public method to indicate that the current method has transactions. Assign a value to the attribute of the annotation to indicate the specific isolation level, propagation behavior, exception information, etc.

   @ All optional properties of Transactional:

        ① Propagation: used to set transaction propagation properties. The property type is propagation enumeration, and the default value is

          Propagation.REQUIRED.

        ② Isolation: used to set the isolation level of transactions. The property type is isolation enumeration, and the default value is

          Isolation.DEFAULT.

        ③ readOnly: used to set whether the operation of this method on the database is read-only. The attribute is boolean, and the default is

          false.

        ④ Timeout: used to set the timeout period for the connection between this operation and the database. The unit is seconds, the type is int, and the default value is - 1,

          That is, there is no time limit.

        ⑤ rollbackFor: Specifies the exception Class that needs to be rolled back. The type is Class [], and the default value is an empty array. Of course, if there is only one

          When an exception class, you can not use an array.

        ⑥ rollbackForClassName: Specifies the name of the exception class that needs to be rolled back. The type is String [], and the default value is an empty array.

          Of course, if there is only one exception class, you can not use an array.

        ⑦ noRollbackFor: Specifies the exception Class that does not need to be rolled back. The type is Class [], and the default value is an empty array. Of course, if only

          When there is an exception class, you can not use an array.

        ⑧ noRollbackForClassName: Specifies the name of the exception class that does not need to be rolled back. The type is String [], and the default value is null

          Group. Of course, if there is only one exception class, you can not use an array.

    It should be noted that @ Transactional can only be used on public methods if it is used on methods. For other non-public methods, if the annotation @ Transactional is added, although Spring will not report an error, it will not weave the specified Transaction into the method. Because Spring ignores the @ Transaction annotation on all non public methods. If @ Transaction is annotated on a class, it means that all methods on the class will be woven into the Transaction at execution time.

5.4.2 declaration transaction manager

    Declare the transaction manager in the Spring configuration file applicationContext.xml.

<!--use spring Transaction processing for-->
<!--1.Claim transaction manager-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <!--You need to know the information of the connected database and specify the data source-->
    <property name="dataSource" ref="myDataSource"/>
</bean>

5.4.3   Enable annotation driven

    Transaction manager: id of the transaction manager bean.

<!--2.Turn on the transaction annotation driver and tell spring Use annotations to manage transactions and create proxy objects
    transaction-manager: Of the transaction manager object id
-->
<tx:annotation-driven transaction-manager="transactionManager"/>

5.4.4   Add transaction attributes to the public method of the business layer

package com.bjpowernode.service.impl;

import com.bjpowernode.dao.GoodsDao;
import com.bjpowernode.dao.SaleDao;
import com.bjpowernode.domain.Goods;
import com.bjpowernode.domain.Sale;
import com.bjpowernode.excep.NotEnoughException;
import com.bjpowernode.service.BuyGoodsService;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;


public class BuyGoodsServiceImpl implements BuyGoodsService {

    private SaleDao saleDao;
    private GoodsDao goodsDao;

    public void setSaleDao(SaleDao saleDao) {
        this.saleDao = saleDao;
    }

    public void setGoodsDao(GoodsDao goodsDao) {
        this.goodsDao = goodsDao;
    }


    /**
     *
     *  rollbackFor: Indicates that the specified exception must be rolled back
     *      Processing logic:
     *          1)spring The framework will first check whether the exception thrown by the method is in the property value of rollbackFor
     *            If the exception is in the rollbackFor list, no matter what type of exception it is, it must be rolled back.
     *          2)If the exception you throw is no longer in the rollbackFor list, spring will judge whether the exception is a RuntimeException,
     *            If yes, it must be rolled back.
     */
    /*@Transactional(propagation = Propagation.REQUIRED,
            isolation = Isolation.DEFAULT,
            readOnly = false,
            rollbackFor = {
                  NullPointerException.class,NotEnoughException.class
            }
            )*/
    //The DEFAULT value of transaction control is used. The DEFAULT propagation behavior is REQUIRED and the DEFAULT isolation level is DEFAULT
    //By default, a runtime exception is thrown and the transaction is rolled back.
    @Transactional
    @Override
    public void buy(Integer goodsId, Integer nums) {
        System.out.println("===buy Start of method===");
        //Record sales information and add records to the sales table
        Sale sale = new Sale();
        sale.setGid(goodsId);
        sale.setNums(nums);
        saleDao.insertSale(sale);
        //Update inventory
        Goods goods = goodsDao.selectGoods(goodsId);
        if(goods == null){
            //Item does not exist
            throw new NullPointerException("The number is:" + goodsId + ",Item does not exist");
        }else if(goods.getAmount() < nums){
            //Insufficient inventory of purchased goods
            throw new NotEnoughException("The number is:" + goodsId + ",Insufficient inventory of goods");
        }
        //Modify inventory
        Goods buyGoods = new Goods();
        buyGoods.setId(goodsId);
        buyGoods.setAmount(nums);
        goodsDao.updateGoods(buyGoods);
        System.out.println("===buy Method completion===");
    }
}

5.4.5 test code

public class MyTest {

    @Test
    public void test01(){
        String config = "applicationContext.xml";
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(config);
        //Get service from container
        BuyGoodsService service = (BuyGoodsService) applicationContext.getBean("buyGoodsService");

        //Call method
        service.buy(1001,200);//If the quantity is too large, an exception will be generated and rollback will occur

    }
}

5.4.6    summary

    spring uses the aop mechanism to create the proxy object of the class where @ Transactional is located, and adds the transaction function to the method.

         Before the execution of your business method, start the transaction first, commit or roll back the transaction after the execution of the business method, and use the aop ring

       Bypass notification @ Around:

                @ Around("business method name of the transaction function you want to add")

                public Object myAround(){

                         Start the transaction and spring will start it for you

                        try{

                                buy(1001,10);

                                 spring's transaction manager. commit();

                        }catch(Exception e){

                                 spring's transaction manager. rollback();

                        }

                }

    The annotation scheme is suitable for small and medium-sized projects.

5.5 AOP configuration management transactions using AspectJ

    It is suitable for large projects. There are many classes and methods, and a large number of configuration transactions are required. Use the aspectj framework function to declare the transactions required by classes and methods in the spring configuration file. In this way, the business method and transaction configuration are completely separated.

5.5.1 adding Aspectj dependency

<!--aspectj rely on-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.2.5.RELEASE</version>
</dependency>

5.5.2 declaration transaction manager

<!--Declarative transaction: completely separate from source code-->
<!--1.Claim transaction manager-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="myDataSource"/>
</bean>

5.5.3 configuring transaction notifications

<!--2.Declare the transaction attributes of the business method (isolation level, propagation behavior, timeout)
    id: Custom name, indicating<tx:advice>and</tx:advice>Configuration content between
    transaction-manager: Of the transaction manager object id
-->
<tx:advice id="myAdvice" transaction-manager="transactionManager">
    <!--tx:attributes: Configure transaction properties-->
    <tx:attributes>
        <!--tx:method: Configure transaction attributes for specific methods, method There can be multiple methods to set transaction attributes for different methods
            name: Method name, 1)Complete method name without package and class
                           2)Method names can use wildcards*,Represents any character
            propagation: Propagation behavior, enumeration value
            isolation: Isolation level
            rollback-for: The exception class name you specified, the fully qualified class name. If an exception occurs, it must be rolled back.
        -->
        <tx:method name="buy" propagation="REQUIRED" isolation="DEFAULT" 
           rollback-for="java.lang.NullPointerException,com.bjpowernode.excep.NotEnoughException"/>
        <!--Use wildcards to specify many methods-->
        <tx:method name="add*" propagation="REQUIRES_NEW"/>
        <!--Specify modification method-->
        <tx:method name="modify*"/>
        <!--Specify the deletion method-->
        <tx:method name="remove*"/>
        <!--Query method, query,search,find-->
        <tx:method name="*" propagation="SUPPORTS" read-only="true"/>
    </tx:attributes>
</tx:advice>

5.5.4 configuration of intensifier

<!--to configure aop-->
<aop:config>
    <!--Configure pointcut expression: specify which classes in which packages and methods to use
        id: The name and unique value of the pointcut expression
        expression: Pointcut expressions that specify which classes use transactions, aspectj The proxy object is created
        
        com.bjpowernode.service
        com.crm.service
        com.service
    -->
    <aop:pointcut id="servicePt" expression="execution(* *..service..*.*(..))"/>

    <!--Configuring enhancers: associations advice and pointcut
        advice-ref: Notice, above tx:advice Configuration there
        pointcut-ref: Of pointcut expressions id
    -->
    <aop:advisor advice-ref="myAdvice" pointcut-ref="servicePt"/>
</aop:config>

5.5.6 test code

public class MyTest {

    @Test
    public void test01(){
        String config = "applicationContext.xml";
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(config);
        //Get service from container
        BuyGoodsService service = (BuyGoodsService) applicationContext.getBean("buyGoodsService");
        //Service = com.sun.proxy. $proxy12 (dynamic proxy, AOP)
        System.out.println("service = " + service.getClass().getName());
        //Call method
        service.buy(1001,10);

    }
}

PS: sort out according to the power node course. If there is infringement, contact to delete it.

Tags: MySQL Spring Java framework Transaction

Posted on Tue, 02 Nov 2021 16:18:32 -0400 by spags