@Propagación de transacciones transaccionales
datos de tabla sin procesar
@Transactional() controla el elemento de configuración de la propagación de transacciones (propagación predeterminada.REQUIRED)
@Transactional(propagation=Propagation.REQUIRED) //控制事务传播。默认是Propagation.REQUIRED
@Transactional(isolation=Isolation.DEFAULT) //控制事务隔离级别。默认跟数据库的隔离级别相同
@Transactional(readOnly=false) //控制事务可读写、只可读。默认可读写
@Transactional(timeout=30) //控制事务的超时时间,单位秒。默认跟数据库的事务控制系统相同
@Transactional(rollbackFor=RuntimeException.class) //控制事务遇到哪些异常会回滚。默认是RuntimeException
@Transactional(rollbackForClassName=RuntimeException) //同上
@Transactional(noRollbackFor=NullPointerException.class) //控制事务遇到哪些异常不会回滚。默认遇到RuntimeException回滚
@Transactional(noRollbackForClassName=NullPointerException)//同上
@Transactional
Esta vez usaremos la anotación predeterminada sin agregar ningún parámetro.
Y no utilice **try{}catch{}** para detectar excepciones.
método de llamada similar
Un método similar llama al método B
1. Tanto el método A como el método B del mismo tipo tienen @Transactional
anotaciones.
@Service
public class A_Service {
@Resource
UserMapper userMapper;
@Transactional
public void A(){
User user = new User();
user.setId(5);
user.setEmail("A");
userMapper.updateById(user);
B();
}
@Transactional
public void B(){
User user = new User();
user.setId(5);
user.setEmail("B");
userMapper.updateById(user);
throw new RuntimeException("B方法业务异常");
}
}
Luego pruebe el método usando la clase de prueba.
@SpringBootTest
public class TransactionalTest {
@Resource
A_Service a_Service;
@Test
public void test(){
a_Service.A();
}
}
resultado de la operación
Luego verifique si los datos de la base de datos se revierten.
Puede ver que los datos se han revertido.
@Transactional
Cuando se anotan el método A y el método B del mismo tipo, cuando el método A llama al método B, el método B tiene sus propias transacciones, pero el método A también tiene transacciones, y el método B se agregará a las transacciones del método A.Por lo tanto, si se produce una excepción en cualquier lugar de A o B, se revertirá.
2. El método A tiene @Transactional
anotaciones, el método B no.
Modificar el método B :
public void B(){
User user = new User();
user.setId(5);
user.setEmail("B");
userMapper.updateById(user);
throw new RuntimeException("B方法业务异常");
}
Pruebe nuevamente y luego vea si los datos de la base de datos se revierten
@Transactional
Cuando se anota el mismo método tipo A, cuando el método B no lo tiene, cuando el método A llama al método B, el método A tiene una transacción, pero el método B no, y el método B se agregará al transacción del método A.Por lo tanto, si se produce una excepción en cualquier lugar de A o B, se revertirá.
3. El método A no tiene @Transactional
anotaciones, el método B tiene @Transactional
anotaciones
Modificar un método
public void A(){
User user = new User();
user.setId(5);
user.setEmail("A");
userMapper.updateById(user);
b_service.B();
}
Pruebe nuevamente y luego vea si los datos de la base de datos se revierten
Se puede ver que los datos han sido modificados tanto por el método A como por el método B.
Muestra que cuando el método A llama al mismo tipo de método B, el método B descubre que el método A no tiene transacción. Por lo tanto, su propia transacción no tendrá efecto, por lo que no se revertirá ningún SQL.
Método de llamada heterogéneo
Un método de clase A llama al método de clase B B
@Transactional
1. Hay anotaciones para el método Clase A y el método Clase B.
Clase A:
@Service
public class A_Service {
@Resource
UserMapper userMapper;
@Resource
B_Service b_service;
@Transactional
public void A(){
User user = new User();
user.setId(5);
user.setEmail("A");
userMapper.updateById(user);
b_service.B();
}
}
Clase B:
@Service
public class B_Service {
@Resource
UserMapper userMapper;
@Transactional
public void B(){
User user = new User();
user.setId(5);
user.setEmail("B");
userMapper.updateById(user);
throw new RuntimeException("B方法业务异常");
}
}
Luego pruebe el método usando la clase de prueba.
@SpringBootTest
public class TransactionalTest {
@Resource
A_Service a_Service;
@Test
public void test(){
a_Service.A();
}
}
resultado de la operación
Luego verifique si los datos de la base de datos se revierten.
Puede ver que los datos se han revertido.
@Transactional
Cuando se anotan el método A de la clase A y el método B de la clase B, cuando se llama al método B de la clase B, el método B tiene su propia transacción, pero el método A también tiene una transacción, y el método B será agregado a la transacción del método A.Por lo tanto, si se produce una excepción en cualquier lugar de A o B, se revertirá.
2. El método A de la clase A tiene @Transactional
anotaciones, pero el método B de la clase B no.
Modificar el método B clase B :
public void B(){
User user = new User();
user.setId(5);
user.setEmail("B");
userMapper.updateById(user);
throw new RuntimeException("B方法业务异常");
}
Pruebe nuevamente y luego vea si los datos de la base de datos se revierten
Puede ver que los datos se han revertido.
Cuando el método A de la clase A tiene
@Transactional
anotaciones, el método B de la clase B no las tiene.Cuando el método A de la clase A llama al método B de la clase B, el método B de la clase B se unirá a la transacción del método A de la clase A. Entonces, la clase B y el método B informan un error y el SQL de los dos métodos se revertirá.
Si la excepción se produce después de llamar al método B clase B, si ocurre una excepción en el método A clase A o en el método B clase B, la transacción se revertirá.
3. Un método de clase A no tiene @Transactional
anotaciones y el método B de clase B tiene @Transactional
anotaciones.
Modificar un método de clase A
public void A(){
User user = new User();
user.setId(5);
user.setEmail("A");
userMapper.updateById(user);
b_service.B();
}
Pruebe nuevamente y luego vea si los datos de la base de datos se revierten
Se puede ver que los datos se modifican mediante el método A de la clase A, pero los datos del método B de la clase B se revierten.
Muestra que cuando el método A de la clase A llama al método B de la clase B, el método B de la clase B encuentra que el método A de la clase A no tiene transacción, pero creará una transacción si tiene una transacción. pero el método A de la clase A todavía no retrocederá.
Si la excepción ocurre después de llamar al método B de la clase B y ocurre una excepción en el método A de la clase A, entonces se ejecutarán tanto el SQL del método A como el método B y la transacción no se revertirá.
Resumir
Descubrimos que las transacciones similares y heterogéneas son aproximadamente iguales. Por ejemplo, tanto el método A de Clase A como el método B de Clase B tienen anotaciones @Transactional
, y el método de Clase A A tiene @Transactional
anotaciones, y los métodos de Clase B B tienen el mismo efecto sin anotaciones.
Pero hay una diferencia: el mismo método tipo A no tiene @Transactional
anotaciones, el método B tiene @Transactional
anotaciones y el método A tipo A no tiene @Transactional
anotaciones, y el método B tipo B tiene @Transactional
anotaciones, y los resultados obtenidos son diferentes.
esta prueba ha terminado