Spring (transaction management, transaction propagation behavior, integration with MyBatis)

VIII Spring transaction management

A transaction can be regarded as a unit * * (whole) * *, which is composed of several operations on the database. When we develop enterprise applications, the most common operation for business members is the combination of multi-step operations for data reading and writing. Exceptions may occur at any step during the sequential execution of the and the database, which will lead to the failure of subsequent operations. At this time, because the business logic is not completed correctly, the data of previous successful operations is not reliable, so it is necessary to fallback in this case.

The function of transaction is to ensure that each operation of the user is reliable. Each step of the transaction must be successfully executed. As long as there is an exception, it will fall back to the state where no operation was performed at the beginning of the transaction. These operations are either completed or cancelled, so as to ensure that the data meets the requirements of consistency.

This is the atomicity (indivisibility) of transactions

Transactions in Spring can be divided into two forms: programmatic transactions and declarative transactions

Programming transactions:

It is rarely used in projects. This method needs to inject a transaction management object TransactionTemplate, and then write our own code to implement it when we need to commit or roll back transactions in our code.

Declarative transaction:

Declarative transaction management is based on AOP. Its essence is to intercept before and after methods, so declarative transactions are method level.

Spring declares that there are two ways to manage transactions:

xml based configuration

Annotation based implementation

Spring transaction management APIPlatformTransactionManager transaction manager interface spring provides different implementation classes for different dao frameworks. The implementation classes of JDBC and mybatis transaction management are DataSourceTransactionManager

Configuration steps:

First configure the transaction manager:

<!-- to configure spring Transaction management class, And inject the data source --> 
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"></property> 
</bean>

Specific implementation:

(1) xml based configuration (understand)

 <!--to configure spring Transaction propagation behavior, This is spring A unique function of the framework-->
    <tx:advice id="txadvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="save" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>

<!--Configure transaction management-->
    <aop:config>
        <aop:pointcut id="save" expression="execution(* com.ffyc.spring.dao.UserDao.save())"/>
        <aop:advisor advice-ref="txadvice" pointcut-ref="save"></aop:advisor>
    </aop:config>

(2) Annotation mode configuration [important]

Enable annotation transaction management

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

Control transactions:

Controlling transactions in a service

@Service(value="userservice")

@Transactional**(propagation=Propagation.REQUIRED) (the content in parentheses is the definition of transaction propagation behavior)**

IX Transaction propagation behavior

Note: the Spring transaction propagation behavior is a unique function of the Spring framework

What is transaction propagation behavior?

Since it is a transaction, there are at least two things that can propagate. Monomer does not spread this behavior.

Transaction propagation behavior refers to how a transaction method is called by another transaction method. Transaction propagation behavior is a unique transaction enhancement feature of Spring framework. It does not belong to the behavior of transaction provider database.

For example:

When the methodA transaction method calls the methodB transaction method, does methodB continue to run in the caller's methodA transaction or start a new transaction for itself? This is determined by the transaction propagation behavior of methodB.

Spring defines seven transaction propagation behaviors:

The following focuses on three transaction propagation behaviors:

  1. PROPAGATION_REQUIRED

The specified method must be executed within the current transaction. If there is a current transaction, it will be added to the current transaction. If there is no current transaction, a new transaction will be created. It is also the default propagation behavior of Spring.

Propagation.REQUIRED A method propagation behavior REUIRQE calls B method propagation behavior is also REQUIRED, then B transaction will be added to B transaction for execution. Method A has no transaction and calls method B. the propagation behavior of method B is also REQUIRED. Then method B will start A transaction by itself

2.PROPAGATION_SUPPORTS

The current transaction is supported. If there is no current transaction, it will be executed in a non transaction manner.

Propagation. The propagation behavior of SUPPORTS A method is that REUIRQE calls B method. If the propagation behavior of B method is SUPPORTS, then B transaction will be added to A transaction for execution. Method A calls method B without transaction. If the propagation behavior of method B is SUPPORTS, method B will execute in A non transaction method

3.PROPAGATION_REQUIRES_NEW

Always create a new transaction. If there is a current transaction, suspend the current transaction until the new transaction ends.

Method a propagation behavior REUIRQE, method B propagation behavior requirements_ New, then method B will start an independent new transaction execution, and B will not be affected by A. Method a has no transactions, and the propagation behavior of the transactions of method B is requirements_ New, then method B will start an independent new transaction execution

Scenario for declaring that the transaction does not take effect:

(1) @ Transactional is applied to non public modified methods

(2) @ Transactiona annotation attribute propagation setting error

(3) Method calls in the same class cause @ Transactional to fail

(4) Exception caught by catch leads to @ Transactional failure

(5) Database engine does not support

X Spring integrates MyBatis

Spring integrates MyBatis. Its core is to hand over SqlSeesionFactory to spring for management, and spring manages the proxy implementation of dao interface

Steps:

The first step is to import relevant jar packages (Note: we are from Spring Helloworld and built):

To import more

All jar packages are here:

<!--mybatis of jar package-->
<dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>    
            <version>3.4.2</version>
        </dependency>

        <!-- mysql of jar package-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.16</version>
        </dependency>

        <!--log4j of jar package-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

        <!-- Unit test jar package-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>provided</scope>
        </dependency>


    <!-- spring-context -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.2.RELEASE</version>
    </dependency>

   <!-- spring-aspects -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.2.2.RELEASE</version>
        </dependency>

  <!-- spring-jdbcs -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.2.2.RELEASE</version>
        </dependency>

  <!--druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>

  <!-- mybatis-spring-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.1</version>
        </dependency>

      

Note: the reason why the screenshot code is popular is the code opened in the format of ordinary file rather than java format

Step 2: configure mybatis based on the original Spring project configuration

Details of newly added configuration:

  • log4j.properties: file for storing log4j configuration information
  • mybatis-config.xml: mybatis core configuration file. However, because spring is integrated, some configurations have been implemented by spring, so some attributes and configuration information should be deleted to avoid errors. The final configuration is as follows:
<?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">
<!--
  mybatis Core profile
-->
<configuration>



	<!--Global configuration-->
	<settings>
		<!--Configuration log implementation log4j   add to log4j Log component import jar Package configuration properties file-->
		<setting name="logImpl" value="LOG4J"/>
		<!--Whether to enable automatic hump naming mapping, that is, from the classic database column name A_COLUMN Map to classic Java Attribute name aColumn. -->
		<setting name="mapUnderscoreToCamelCase" value="true"/>
		<!--<setting name="lazyLoadingEnabled" value="true"/>-->
		<!--lazyLoadTriggerMethods Specify which methods trigger deferred loading-->
		<setting name="lazyLoadTriggerMethods" value=""/>
		<!--Enable global L2 cache configuration-->
		<setting name="cacheEnabled" value="true"/>
	</settings>

	<typeAliases>
		<package name="com.ffyc.ssm.model"/>     <!--The package of the corresponding specific entity is configured, and all aliases are directly defined at one time mapper.xml When used in, you don't have to write the full class name-->
	</typeAliases>

</configuration>

  • spring_mybatis.xml: use spring to manage the package of SqlSeesionFactory objects and interface proxy objects

Specific code:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">
        
    <!-- spring Management generation SqlSessionFactory,read mybatis Various configurations-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="druidDataSource"></property>
        <property name="configLocation" value="classpath:mybatis-config.xml"></property>
        <property name="mapperLocations" value="classpath:mapper/*Mapper.xml"></property>
    </bean>
    <!--Generate the interface proxy object under the specified package-->
    <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.ffyc.ssm.dao"></property>
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
    </bean>
</beans>

Step 3: (add mybatis to Spring) create sql mapping file

Step 4: operate the returned data according to the requirements in the service layer

Keywords: Java Spring Back-end

Added by psych0 on Thu, 06 Jan 2022 00:42:31 +0200