Spring study notes-06 transacción declarativa

Revisemos las transacciones en la base de datos: las transacciones tienen cuatro características: atomicidad, consistencia, aislamiento, durabilidad, conocidas como ACID.

Atomicidad : Una transacción es una unidad lógica de trabajo en la base de datos. Las operaciones contenidas en la transacción tienen éxito o fallan .

Coherencia : el resultado de la ejecución de la transacción debe ser cambiar la base de datos de un estado coherente a otro estado coherente. Una vez que la transacción se ejecuta correctamente, la base de datos está en un estado coherente. Si se produce un error durante la ejecución y parte de la modificación realizada por la transacción se ha escrito en la base de datos física, la base de datos se encuentra en un estado inconsistente.

Aislamiento : La ejecución de una transacción no puede afectar la ejecución de otras transacciones. Las operaciones internas y los datos usados ​​por una transacción están aislados de otras transacciones, y las transacciones ejecutadas simultáneamente no interfieren entre sí .

Persistencia : una vez que se confirma una transacción, su modificación a la base de datos es permanente , y otras operaciones posteriores no tendrán ningún impacto en el resultado de esta modificación.

Probemos la transacción de SqlSessionTemplate: ajuste Dao para ver la transacción a través del Servicio

UserService.java

package com.zt.Service;

public interface UserService {
    void testTransaction();
}

UserServiceImpl.java

package com.zt.Service.Impl;

import com.zt.Dao.UserDao;
import com.zt.Eneity.User;
import com.zt.Service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    public void testTransaction() {

        int i = userDao.addUser(new User(2,"zzt","zjm"));
        System.out.println(i);

        int j = 1 / 0;

        userDao.updateUserById(new User(2,"withstand","pain"));

    }
}

TestTranscation.java

import com.zt.Service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring-config.xml")
public class TestTranscation {
    
    @Autowired
    private UserService userService;

    @Test
    public void testTranscation(){
        userService.testTransaction();
    }

}

[Nota]: Para poder inyectar aquí con éxito, necesitamos activar el paquete de escaneo automático Spring y convertir la clase de entidad de UserServiceImpl en un Bean y registrarlo en el contenedor Spring.

Resultados de:

Obviamente, ocurrió una excepción de división por 0. Ahora veamos los datos en la base de datos:

Se puede ver que la operación antes de la excepción se ejecuta y la operación posterior a la excepción no, este método de negocio no se gestiona por transacciones, porque no se satisface la atomicidad de las cosas, lo que nos obliga a agregar transacciones manualmente.

Spring admite transacciones programáticas y transacciones declarativas:

Transacción programática: recuerde que confirmamos o deshacemos manualmente en Mybatis, y controlamos directamente el envío y la reversión de cosas mediante la inserción de código. Esta es una transacción programática.

Transacciones declarativas: las transacciones programáticas requieren que incrustemos código para cada método que requiera que las cosas se transformen, pero esto es mucho trabajo y repetitivo; hemos aprendido AOP antes y las transacciones declarativas están integradas en la gestión de transacciones a través de AOP. Code.

1. Importar restricción tx

xmlns:tx="http://www.springframework.org/schema/tx"

http://http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd

2. Administrador de transacciones

Ya sea que use programática o declarativa, debe hacerse a través del administrador de transacciones, que encapsula un conjunto de métodos independientes de la tecnología.

A. Transacción JDBC

1) Registrarse como Bean

    <bean id="transcationManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

2) Abra el administrador de transacciones con anotaciones

<tx:annotation-driven transaction-manager="transcationManager"/>

3) Utilice la anotación @Transactional para convertir el método en una transacción

    @Transactional
    public void testTransaction() {

        int i = userDao.addUser(new User(3,"zzt","zjm"));
        System.out.println(i);

        int j = 1 / 0;

        userDao.updateUserById(new User(3,"withstand","pain"));

    }

4) Prueba

En este punto, todo el método comercial se convierte en una transacción.

Como hemos aprendido antes, las operaciones de adición, eliminación y modificación involucradas en el mapeador construido por SqlSession solo se actualizarán en la base de datos cuando se envíen, y SqlSessionTemplate realmente nos ayuda a confirmar o revertir la adición, eliminación y modificación de un solo mapeador, pero el ejemplo está involucrado Las dos operaciones se fusionan en un método comercial, por lo que debemos transformar el método en sí en una transacción.

B. El archivo de configuración permite transacciones declarativas

    <bean id="transcationManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--配置事务通知-->
    <tx:advice id="txAdvice" transaction-manager="transcationManager">
        <tx:attributes>
            <!--配置哪些方法用什么样的事务,配置事物的传播特性-->
            <tx:method name="add*" propagation="REQUIRED"/>
            <tx:method name="delete*" propagation="REQUIRED"/>
            <tx:method name="update*" propagation="REQUIRED"/>
            <tx:method name="search*" propagation="REQUIRED"/>
            <!--查询无需事务 设置只读-->
            <tx:method name="get*" read-only="true"/>
            <tx:method name="find*" read-only="true"/>
            <tx:method name="*" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>

    <!--用AOP织入事务-->
    <aop:config>
        <aop:pointcut id="txPointCut" expression="execution(* com.zt.Service.Impl.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
    </aop:config>

Elimine la configuración del modo de anotación de transacciones en el archivo de configuración y elimine @Transactional en el método. Después de la prueba, se puede ver que la transacción se abrió correctamente.

Explicación detallada de las características de propagación de transacciones:

El comportamiento de propagación de transacciones es cómo se propagan las transacciones entre estos métodos cuando varios métodos de transacción se llaman entre sí. Spring admite 7 comportamientos de propagación de transacciones:

Tipo de comportamiento de propagación de transacciones Descripción
PROPAGATION_REQUIRED Si no hay ninguna transacción actualmente, cree una nueva transacción, si ya hay una transacción, únase a ella. Ésta es la opción más común.
PROPAGATION_SUPPORTS Admite la transacción actual, si no hay ninguna transacción actualmente, se ejecuta de manera no transaccional.
PROPAGATION_MANDATORY Usa la transacción actual y lanza una excepción si no hay ninguna transacción actual.
PROPAGATION_REQUIRES_NEW Cree una nueva transacción. Si existe una transacción, suspenda la transacción actual.
PROPAGATION_NOT_SUPPORTED La operación se realiza de manera no transaccional, si hay una transacción actualmente, se suspende la transacción actual.
PROPAGATION_NEVER Ejecutar de manera no transaccional. Si hay una transacción actualmente, se lanza una excepción.
PROPAGATION_NESTED Si una transacción existe actualmente, se ejecuta dentro de una transacción anidada. Si no hay ninguna transacción actualmente, realice una operación similar a PROPAGATION_REQUIRED.

El método de propagación de transacciones predeterminado de Spring es REQUERIDO, que es adecuado para la mayoría de las situaciones.

Supongo que te gusta

Origin blog.csdn.net/qq_39304630/article/details/112587261
Recomendado
Clasificación