Su comentario fracaso @Transaction todavía?

introducción

En el proyecto se utilizan a menudo @Transaction anotación de control de transacciones, pero a veces inexplicables sin este control transacción no trabajo, durante la entrevista, el entrevistador puede preguntar @Transaction comentario ¿En qué circunstancias sería un fracaso? Hoy acabo veo un artículo escrito sobre esto, así que resolver.

Una transacción

Sabemos que en la primavera para llevar a cabo en el marco del control de transacciones, tenemos dos maneras. En primer lugar, [ control de transacciones programática ], el segundo [ de control de transacciones declarativa ].

[ Control de transacciones programática ]

Concepto: Como su nombre indica, es lo que podemos controlar la transacción por medio de código de programación

Desventajas: Código altamente invasivos

Ejemplo:

tratar {
     // TODO algo 
     transactionManager.commit (el estado);
} Catch (Exception e) {
    transactionManager.rollback (status);
    de banda  nueva nueva InvoiceApplyException ( "anormal falló" );
}

[ Control de transacciones declarativa ]

Concepto: Basado en AOP Aspect-orientado, y será específica transacción de negocios desacoplamiento parcial.

Pros: Código Código de desacoplamiento de control de transacciones y nuestro negocio específico, código, menos invasiva. Por lo tanto, el proceso de desarrollo real, este método es el más utilizado. transacción declarativa, hay dos maneras, uno se basa en el archivo de configuración XML y modo TX de AOP , la segunda se basa en @Transaction comentario

Dos, @ introducción de transacción

  1. @ Transacción anotación se puede utilizar en su lugar

    @Transaction puede actuar interfaces, clases, métodos de clase

  • la clase de acción: los métodos de la clase pública se configuran con la misma información de atributo de transacción.
  • El papel de los métodos de la clase: configuración de clase cuando un @Transaction, el método también @Transaction configure, la transacción se anulará el método de la clase de información de configuración de transacción
  • El papel de interfaz: No se recomienda este método, ya que una vez marcado en la interfaz y configurar primavera AOP utilizando dinámica de proxy CGLIB, conducirá al fracaso comentario @Transaction  
@Transactional
 @RestController
 @RequestMapping
 público  de clase MybatisPlusController {
     @Autowired
     privada cityInfoDictMapper CityInfoDictMapper;
 
     @Transactional (rollbackFor = Excepción. Clase )
     @GetMapping ( "/ test" )
     pública Prueba de la cuerda () lanza la excepción {
        CityInfoDict cityInfoDict = nuevo CityInfoDict ();
        cityInfoDict.setParentCityId ( 2 );
        cityInfoDict.setCityName ( "2" );
        cityInfoDict.setCityLevel ( "2" );
        cityInfoDict.setCityCode ( "2" );
        int inserto = cityInfoDictMapper.insert (cityInfoDict);
        volver inserto + "" ;
    }
}

2. Propiedades de transacción @

①propagation

propagación comportamiento de la propagación en nombre de la transacción. El valor por defecto Propagation.REQUIRED.

 

Propagation.REQUIRED: Si existe la transacción actual, que se añade a la transacción, si la transacción no existe actualmente, crear una nueva transacción (es decir, si A y métodos B son métodos para agregar anotaciones en el modo de propagación por defecto, un método. llamada interna B, la transacción será combinar los dos métodos una transacción)

Propagation.SUPPORTS: Si existe la transacción actual, que se añade a la transacción, y si la transacción no existe en la actualidad, el camino no transaccional que continúe la marcha

Propagation.MANDATORY: Si existe la transacción actual, que se añade a la transacción, si la transacción no existe en la actualidad, se produce una excepción.

Propagation.REQUIRES_NEW: re-crear una nueva transacción, si existe en la actualidad la transacción, suspender la transacción actual (Procedimiento A en un modo de corriente predeterminado Propagation.REQUIRED, b más el método del modo de clase B Propagation.REQUIRES_NEW emplea, a continuación. una llamada de método b método para operar la base de datos, pero después de un método produce una excepción, método B no deshacer una transacción será suspendido porque el método Propagation.REQUIRES_NEW)

Propagation.NOT_SUPPORTED: por medio de la operación no transaccional, si existe la transacción actual, suspender la transacción actual

Propagation.NEVER: por medio de la operación no transaccional, si existe la transacción actual, se produce una excepción

Propagation.NESTED: Propagation.REQUIRED y el mismo efecto.

propiedad ②isolation

nivel de aislamiento de la transacción: Aislamiento

propiedad ③timeout

tiempo de espera de la transacción, el valor predeterminado es -1. Si la transacción excede el límite de tiempo no se ha completado aún, la reversión automática.

propiedad ④readOnly

Especificar de sólo lectura si la transacción se transacciones, el valor predeterminado es false; método que no requiere la operación de ignorar, tales como la lectura de datos, se puede establecer en cierto

⑤rollbackFor propiedad

Se utiliza para especificar el tipo de transacción de reversión puede desencadenar una excepción, puede especificar varios tipos de excepción

⑥noRollbackFor propiedad

Especifica es lanzado el tipo de excepción, la transacción no va a cambiar, también se pueden especificar varios tipos de excepción.

Tres, @ escenarios de fallo de transacción

① aplicado a los métodos no modificados públicas. La razón es porque el fracaso agente primavera AOP es, como se muestra, TransactionInterceptor (interceptor transacción) para objetivo de intercepción antes y después de la ejecución del método, (clase interna CglibAopProxy) método de intercepción DynamicAdvisedInterceptor JDKDynamicAopProxy o método indirectamente invoke llamadas de método computeTransactionAttribute AbstractFallbackTransactionAttributeSource de obtener información de configuración de transacción de la anotación de transacciones.

protegida TransactionAttribute computeTransactionAttribute (método Método,
    Clase <?> TargetClass) {
         // No permita que los métodos no-públicas según sea necesario. 
        si (allowPublicMethodsOnly () &&! Modifier.isPublic (method.getModifiers ())) {
         retorno  nula ;
}

Este método comprueba el método de destino cuando modificadores pública la información de configuración, no el público no va a conseguir @Transaction de la propiedad.

② atributo anotación propiedades de propagación de error.

Si la configuración de tres siguientes atributo de propagación = valor de atributo, no hay ninguna transacción de reversión.

TransactionDefinition.PROPAGATION_SUPPORTS

TransactionDefinition.PROPAGATION_NOT_SUPPORTED

TransactionDefinition.PROPAGATION_NEVER

③rollbackFor error de selección

rollbackFor receta se puede especificar de transacción tipos de excepción rollback .spring predeterminado repartió excepciones sin marcar, sin marcar, (heredadas de RuntimeException excepción) o sólo Error deshacer la transacción; otras prescripciones excepción no deshace la transacción, si tirado en una transacción otros tipos de excepciones, pero que pueden esperar rollo de primavera la transacción, es necesario especificar la propiedad rollbackFor.

Si tirado en el método de destino en una subclase de rollbackFor anormal anormal especificado, la transacción también se deshace.

privada  int getDepth (Clase <?> exceptionClass, int profundidad) {
          si (exceptionClass.getName (). contiene ( este .exceptionName)) {
              // encontrado! 
             volver profundidad;
 }
         // Si hemos ido tan lejos como podemos ir y no lo hemos encontrado ... 
         si (== exceptionClass Throwable. Clase ) {
              retorno de -1 ;
}
retorno getDepth (exceptionClass.getSuperclass (), la profundidad + 1 );
}

④ llamar al mismo método en una clase, resultando en @Transaction fracaso

Por ejemplo, hay una clase Test, que es un método A, A y luego llamar a este tipo de método B (independientemente del método B es la modificación público o privado), cuando el método no se declara asuntos de anotación, mientras que los métodos B, después del método A es llamada final, método de transacción B no está funcionando. esto es porque el uso de proxy de AOP resorte causado, porque sólo cuando el método de transacción es llamada la clase actual de que el código tendrá un objeto proxy de resorte generada por la dirección.

⑤ excepción es su captura "comer" plomo @Transaction al fracaso.

Esta situación es el tipo más común de escenarios de fallo @Transaction comentario

     @Transactional
      privado Entero A () lanza la excepción {
          int inserto = 0 ;
         tratar {
             CityInfoDict cityInfoDict = nuevo CityInfoDict ();
             cityInfoDict.setCityName ( "2" );
             cityInfoDict.setParentCityId ( 2 );
             / **
              * El campo de datos A 2 se inserta
             * / 
            Inserto = cityInfoDictMapper.insert (cityInfoDict);
            / **
             * B 3 se inserta en el campo de datos
             * /
            b.insertB ();
        } Catch (Exception e) {
            e.printStackTrace ();
        }
    }

Si el método B interno una excepción, pero este intento de captura método Un momento del procedimiento B anormales, y que la transacción se puede revertir a la normalidad todavía?

Respuesta: ¡No!

会 抛出 异常: org.springframework.transaction.UnexpectedRollbackException: retrotraído la transacción, ya que se ha marcado como la reversión de sólo

Porque cuando ServiceB una excepción después, ServiceB necesidad de firmar la reversión transacción actual. Serviceâ su debido tiempo a capturar manualmente este control de excepciones, serviceâ que la transacción actual debe comprometerse a la normalidad. En este tiempo no será una inconsistencia, también es tal manera que la parte delantera UnexceptedRollbackException lanza una excepción,

La primavera es una transacción antes de llamar al comienzo de un método de negocio se lleva a cabo sólo después de que el negocio de la ultima método commit o rollback, si no se ejecuta en función de si se produce una excepción en tiempo de ejecución. Si se lanza RuntimeException no cuajó a sus métodos de negocio, a continuación, la transacción se revierte.

En los negocios métodos generalmente no necesitan capturar una excepción, si tiene que coger deben ser expulsados throw new RuntimeException(), o lanzar una excepción especificada tipo de anotación @Transactional(rollbackFor=Exception.class), lo contrario hará que la transacción falle, lo que resulta en datos inconsistentes confirmar datos, así que a veces intentar coger el lugar superfluo.

motor de base de datos no admite transacciones

La probabilidad de que esto ocurra no es muy alta, la transacción puede tener efecto soportes de motor de base de datos transaccionales es la clave. Comúnmente utilizado soportes transacciones de bases de datos MySQL utilizando el valor por defecto innodbdel motor. Una vez que el motor de base de datos no admite el cambio a una transacción myisam, la transacción se producirá un error fundamental.

[Desde arriba] número público marcozheng, https: //mp.weixin.qq.com/s/enKOM3F_Xxg123HPMCFUPw, y estudiada.

 

Supongo que te gusta

Origin www.cnblogs.com/lovehunterYjj/p/12588532.html
Recomendado
Clasificación