Springboot---procesamiento de la configuración de la transacción de la operación mybatis

Tabla de contenido

Prefacio:

asuntos relacionados con el negocio

1. ¿Qué es una transacción?

2. Características de las transacciones (ACID)

3. ¿Cuándo piensa utilizar transacciones?

4. Por lo general, use JDBC para acceder a la base de datos, o mybatis para acceder a la base de datos, ¿cómo manejar las transacciones?

5. ¿Cuáles son las deficiencias en la forma de procesamiento de transacciones en la pregunta?

6. ¿Cómo resolver el problema?

7. Para tratar los asuntos, ¿qué se debe hacer y qué se debe hacer?

8. Nivel de aislamiento de transacciones

9. Tiempo de espera de transacción

10. Comportamiento de propagación de transacciones

Configure transacciones en Spring Boot y use:

1. Realizar el procesamiento de configuración

2. Cree una clase de configuración de recursos de datos:

3. Llame a la práctica en el código real:

Resumir:


Prefacio:

En la actualidad, la mayoría de los proyectos se desarrollan a través de Spring o Springboot, y mybatis\mybatis-plus, etc., se usan comúnmente para operar bases de datos en proyectos. Cuando se operan bases de datos, a menudo se usa el procesamiento de transacciones, porque cuando se operan bases de datos, si ocurre una excepción, todas las operaciones de la base de datos se pueden revertir para evitar problemas con algunos datos anormales. En la actualidad, todas las búsquedas en Internet son los métodos de configuración originales, como usar xml para la configuración de beans, o llamar directamente agregando anotaciones en el encabezado del método.Este artículo presenta principalmente el método de práctica de gestión a través de clases de configuración, que es Gestión unificada , procesamiento unificado.

asuntos relacionados con el negocio

1. ¿Qué es una transacción?

Una transacción se refiere a un conjunto de sentencias SQL. Hay varias sentencias SQL en el conjunto, que se pueden insertar, actualizar, seleccionar y eliminar. Se espera que estas sentencias SQL se ejecuten de forma coherente y como un todo. O todos tienen éxito, o ambos fallan.

2. Características de las transacciones (ACID)

Atomicidad: Una transacción es una operación atómica que consiste en una serie de acciones. La atomicidad de las transacciones garantiza que las acciones se completen por completo o no tengan ningún efecto.

Consistencia: una vez que se completa una transacción (independientemente de si tiene éxito o falla), el sistema debe garantizar que el negocio que modela esté en un estado consistente, en lugar de parcialmente completado y parcialmente fallido. En realidad, los datos no deberían corromperse.

Aislamiento: puede haber muchas transacciones que procesen los mismos datos al mismo tiempo, por lo que cada transacción debe aislarse de otras transacciones para evitar la corrupción de datos.

Durabilidad: una vez que se completa una transacción, sus resultados no deberían verse afectados sin importar qué error del sistema ocurra, para que pueda recuperarse de cualquier bloqueo del sistema. Por lo general, los resultados de las transacciones se escriben en un almacenamiento persistente.

3. ¿Cuándo piensa utilizar transacciones?

(1) Cuando la operación diseña múltiples tablas, o inserta, actualiza y elimina múltiples sentencias SQL. Es necesario asegurarse de que estas declaraciones sean todas exitosas para completar la función, o que todas ellas no cumplan con los requisitos. (O ambos tienen éxito o ambos fallan)

(2) ¿Cómo se utilizan las transacciones en el desarrollo de Java?

1. La transacción se coloca en el método comercial de la clase de servicio, porque el método comercial llamará a múltiples dao y ejecutará múltiples declaraciones SQL

4. Por lo general, use JDBC para acceder a la base de datos, o mybatis para acceder a la base de datos, ¿cómo manejar las transacciones?

(1) jdbc accede a datos y procesa transacciones. conexión conn;conn.commit();conn.rollback();

(2) mybatis accede a la base de datos y procesa transacciones. SqlSession.commit() ;SqlSession.rollback();

(3) hibernate accede a la base de datos y procesa las transacciones, Session.commit(), Session.rollback();

5. ¿Cuáles son las deficiencias en la forma de procesamiento de transacciones en la pregunta?

(1) Diferentes tecnologías de acceso a bases de datos tienen diferentes objetos y métodos para procesar transacciones. Debe comprender cómo las diferentes bases de datos utilizan transacciones.

(2) Es necesario dominar la lógica de procesamiento de varias transacciones de la base de datos, cuándo confirmar la transacción y cuándo revertirla.

(3) Hay muchas maneras de tratar los asuntos.

Resumen: Es una variedad de tecnologías de acceso a bases de datos, diferentes mecanismos de procesamiento de transacciones, objetos y métodos. Difícil de dominar.

6. ¿Cómo resolver el problema?

Spring proporciona un modelo unificado para el procesamiento de transacciones, que puede utilizar pasos y métodos unificados para completar el procesamiento de transacciones de varias tecnologías de acceso a bases de datos. El uso del mecanismo de procesamiento de transacciones de Spring puede completar el procesamiento de transacciones de mybatis e hibernar accediendo a la base de datos.

7. Para tratar los asuntos, ¿qué se debe hacer y qué se debe hacer?

El modelo de transacción de primavera utiliza pasos fijos. Simplemente proporcione a Spring toda la información que se utilizará en la transacción.

(1) La confirmación y reversión internas de la transacción utilizan el objeto del administrador de transacciones en lugar de la confirmación y reversión manuales. Un administrador de transacciones es una interfaz y sus muchas clases de implementación.

Interfaz: PlatformTransactionManager, que define los métodos importantes de compromiso y reversión de la transacción

Clase de implementación: Spring ha creado el procesamiento de transacciones correspondiente a cada tecnología de acceso a la base de datos.

a. Mybatis accede a la base de datos: Spring crea DataSourceTransactionManager

b. Hibernate accede a la base de datos: Spring crea HibernateTransactionManager

¿cómo utilizar?

Simplemente dígale a Spring qué tecnología de acceso a la base de datos (marco) usar, declare la clase de implementación del administrador de transacciones correspondiente a la tecnología de acceso a la base de datos y use la instrucción <bean> en el archivo de configuración de Spring. Por ejemplo, use mybatis para acceder a la base de datos:

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

1

(2) ¿Qué tipo de transacción necesita el método comercial? Describe el tipo de transacción requerida.

8. Nivel de aislamiento de transacciones

Hay 5 valores, uno de los cuales es el predeterminado. Todas estas constantes comienzan con ISOLATION_, lo que significa: ISOLATION_XXX.

1. PREDETERMINADO: utilice el nivel de aislamiento de transacciones predeterminado de la base de datos. Nivel de aislamiento predeterminado de MySQL: REPEATABLE_READ (lectura repetible); Nivel de aislamiento predeterminado de Oracle: READ_COMMITTED (lectura confirmada)

2. READ_UNCOMMITTED: lectura no confirmada, sin problemas de concurrencia resueltos.

3. READ_COMMITTED: se ha enviado la lectura. Resuelva datos sucios, hay lecturas no repetibles y lecturas fantasma.

4. REPEATABLE_READ: Repetibilidad. Resuelva lecturas sucias, lecturas no repetibles y lecturas fantasma.

5. SERIALIZABLE: serialización. No hay problemas de concurrencia.

9. Tiempo de espera de transacción

Indica el tiempo de ejecución más largo de un método, si la ejecución del método excede este tiempo, la transacción se revertirá. La unidad es segundos, un valor entero, el valor predeterminado es: -1 (lo que significa que no hay límite en el tiempo máximo).

10. Comportamiento de propagación de transacciones

Controle si el método comercial tiene una transacción y qué tipo de transacción es. Hay 7 acciones de propagación en total. (Las banderas rojas se usan comúnmente y deben dominarse)

(1) PROPAGATION_REQUIRED: El método especificado debe ejecutarse dentro de la transacción. Si hay una transacción actual, únase a la transacción actual; si no hay una transacción actual, cree una nueva transacción. Este tipo de comportamiento de creación de Bobo es la opción más común y también es el comportamiento de propagación de transacciones predeterminado de Spring.

(2) PROPAGATION_REQUIRES_NEW: siempre crea una nueva transacción. Si hay una transacción actual, suspende la transacción actual hasta que se complete la ejecución de la nueva transacción.

(3) PROPAGATION_SUPPORTS: el método especificado admite la transacción actual, pero si no hay una transacción actual, también se puede ejecutar de forma no transaccional.

(4)PROPAGACIÓN_OBLIGATORIA

(5)PROPAGACIÓN_ANIDADO

(6)PROPAGACIÓN_NUNCA

(7)PROPAGACIÓN_NO_SUPPORTADA

Configure transacciones en Spring Boot y use:

1. Realizar el procesamiento de configuración

#transaction setting###############################################
spring.transaction.aop.aop-pointcut-expression=execution(* com...*ServiceImpl.*(..))
spring.transaction.aop.tx-method-timeout=3600
spring.transaction.aop.require-rule=insert*,update*,delete*,do*
spring.transaction.aop.read-only-rule=query*
spring.transaction.aop.indep-transaction-rule=indep*

La primera configuración: este método es principalmente para escanear la ruta del paquete durante la operación, no todos los métodos son procesamiento de transacciones.

La segunda configuración: el tiempo de procesamiento de la configuración es de 36 segundos

La tercera configuración: para limitar las reglas, por ejemplo, el nombre del método debe comenzar con algo, y solo el nombre del método comienza con la transacción

La cuarta configuración: nombrar al principio del nombre del método de la regla de lectura

La quinta configuración: reglas de procesamiento de transacciones

2. Cree una clase de configuración de recursos de datos:

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource;
import org.springframework.transaction.interceptor.RollbackRuleAttribute;
import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute;
import org.springframework.transaction.interceptor.TransactionAttribute;
import org.springframework.transaction.interceptor.TransactionInterceptor;

@Configuration
public class SpringBootDatasourceConfig {
    private Logger LOGGER = LoggerFactory.getLogger(SpringBootDatasourceConfig.class);
    @Value("${spring.transaction.aop.tx-method-timeout}")
    private int TX_METHOD_TIMEOUT = 60;
    @Value("${spring.transaction.aop.aop-pointcut-expression}")
    private String AOP_POINTCUT_EXPRESSION;
    @Value("#{'${spring.transaction.aop.require-rule}'.split(',')}")
    private List<String> requireRuleList;
    @Value("#{'${spring.transaction.aop.read-only-rule}'.split(',')}")
    private List<String> readOnlyRuleList;
    @Value("#{'${spring.transaction.aop.indep-transaction-rule}'.split(',')}")
    private List<String> indepTransactionRuleList;
    @Value("${mybatis.mapper-locations}")
    private String MYBATIS_MAPPER_LOCATIONS;
    @Value("${mybatis.config-location}")
    private String MYBATIS_CONFIG_LOCATION;
    @Value("${mybatis.jdbc.dialect.type}")
    private String MYBATIS_JDBC_DIALECT_TYPE;

    public SpringBootDatasourceConfig() {
    }

    @Primary
    @Bean({"db1DataSourceProperties"})
    @ConfigurationProperties(
        prefix = "spring.datasource.db1"
    )
    public DataSourceProperties dataSourceProperties() {
        DataSourceProperties dataSourceProperties = new DataSourceProperties();
        return dataSourceProperties;
    }

    @Primary
    @Bean({"db1DataSource"})
    @ConfigurationProperties(
        prefix = "spring.datasource.db1.tomcat"
    )
    public DataSource db1DataSource(@Qualifier("db1DataSourceProperties") DataSourceProperties dataSourceProperties) {
        DataSource dataSource = dataSourceProperties.initializeDataSourceBuilder().build();
        return dataSource;
    }

    @Primary
    @Bean(
        name = {"db1SqlSessionFactory"}
    )
    public SqlSessionFactory db1SqlSessionFactory(@Qualifier("db1DataSource") DataSource datasource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(datasource);
        bean.setMapperLocations((new PathMatchingResourcePatternResolver()).getResources(this.MYBATIS_MAPPER_LOCATIONS));
        bean.setConfigLocation((new PathMatchingResourcePatternResolver()).getResource(this.MYBATIS_CONFIG_LOCATION));
        PageInterceptor pageInterceptor = new PageInterceptor();
        Properties properties = new Properties();
        properties.setProperty("dialect", this.MYBATIS_JDBC_DIALECT_TYPE);
        pageInterceptor.setProperties(properties);
        Interceptor[] plugins = new Interceptor[]{pageInterceptor};
        bean.setPlugins(plugins);
        return bean.getObject();
    }

    @Bean({"sqlSessionTemplate"})
    public SqlSessionTemplate db1SqlsessionTemplate(@Qualifier("db1SqlSessionFactory") SqlSessionFactory sessionfactory) {
        SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sessionfactory);
        if (sqlSessionTemplate != null) {
            Connection connection = null;

            try {
                connection = sqlSessionTemplate.getConnection();
            } catch (Exception var13) {
                this.LOGGER.error("SqlSessionTemplate初始化连接池失败", var13);
            } finally {
                if (connection != null) {
                    try {
                        connection.close();
                    } catch (SQLException var12) {
                        this.LOGGER.error("关闭连接失败", var12);
                    }
                }

            }
        }

        return sqlSessionTemplate;
    }

    @Bean({"txmanager"})
    public DataSourceTransactionManager txManager(@Qualifier("db1DataSource") DataSource dataSource) {
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(dataSource);
        return dataSourceTransactionManager;
    }

    @Bean({"txAdvice"})
    public TransactionInterceptor txAdvice(@Qualifier("txmanager") DataSourceTransactionManager dataSourceTransactionManager) {
        RuleBasedTransactionAttribute readOnlyRule = new RuleBasedTransactionAttribute();
        readOnlyRule.setReadOnly(true);
        readOnlyRule.setPropagationBehavior(4);
        RuleBasedTransactionAttribute requireRule = new RuleBasedTransactionAttribute();
        requireRule.setRollbackRules(Collections.singletonList(new RollbackRuleAttribute(RuntimeException.class)));
        requireRule.setPropagationBehavior(0);
        requireRule.setIsolationLevel(2);
        requireRule.setTimeout(this.TX_METHOD_TIMEOUT);
        RuleBasedTransactionAttribute indepTransactionRule = new RuleBasedTransactionAttribute();
        indepTransactionRule.setRollbackRules(Collections.singletonList(new RollbackRuleAttribute(RuntimeException.class)));
        indepTransactionRule.setPropagationBehavior(3);
        indepTransactionRule.setIsolationLevel(2);
        indepTransactionRule.setTimeout(this.TX_METHOD_TIMEOUT);
        Map<String, TransactionAttribute> txMap = new HashMap();

        int i;
        String indepTransacdtionAopRule;
        for(i = 0; i < this.requireRuleList.size(); ++i) {
            indepTransacdtionAopRule = (String)this.requireRuleList.get(i);
            txMap.put(indepTransacdtionAopRule.trim(), requireRule);
        }

        for(i = 0; i < this.readOnlyRuleList.size(); ++i) {
            indepTransacdtionAopRule = (String)this.readOnlyRuleList.get(i);
            txMap.put(indepTransacdtionAopRule.trim(), readOnlyRule);
        }

        for(i = 0; i < this.indepTransactionRuleList.size(); ++i) {
            indepTransacdtionAopRule = (String)this.indepTransactionRuleList.get(i);
            txMap.put(indepTransacdtionAopRule.trim(), indepTransactionRule);
        }

        NameMatchTransactionAttributeSource nameMatchTransactionAttributeSource = new NameMatchTransactionAttributeSource();
        nameMatchTransactionAttributeSource.setNameMap(txMap);
        TransactionInterceptor txAdvice = new TransactionInterceptor(dataSourceTransactionManager, nameMatchTransactionAttributeSource);
        return txAdvice;
    }

    @Bean
    public Advisor txAdviceAdvisor(@Qualifier("txAdvice") TransactionInterceptor transactionInterceptor) {
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression(this.AOP_POINTCUT_EXPRESSION);
        return new DefaultPointcutAdvisor(pointcut, transactionInterceptor);
    }
}

3. Llame a la práctica en el código real:

El primer método: agregue un método de excepción, llame a la interfaz directamente y podrá ver los efectos relevantes, pero debe agregar lanzamientos de excepción relacionados después de que cambie la base de datos, de modo que todo el método sea anormal y luego verifique que los registros en la base de datos no ha cambiado, se ha revertido;

El segundo método: elimine el método anormal, deje que todo el método continúe ejecutándose normalmente, consulte los registros a través de la base de datos y verifique si los datos se actualizaron o se colocaron con éxito en la base de datos;

Resumir:

En la actualidad, todas las búsquedas en Internet son anotaciones directamente utilizadas para el procesamiento de transacciones, en lugar de reglas de configuración basadas en archivos de configuración, y administración y procesamiento unificados de transacciones. Por ejemplo, los nombres de métodos se procesan en términos de aspectos. El procesamiento de actualización utilizar el procesamiento de transacciones), por ejemplo, muchas grandes empresas en la actualidad, o empresas que necesitan mantener la coherencia de las transacciones lo utilizarán. Toda la cadena de llamadas es relativamente larga. Si hay un problema en el medio, la transacción se revertirá el procesamiento , evitando muchos problemas (el problema de los datos basura en la base de datos);

Supongo que te gusta

Origin blog.csdn.net/qq_25580555/article/details/130987908
Recomendado
Clasificación