Directorio de artículos
-
- 1 El motor de base de datos no admite transacciones.
- 2 clases no son administradas por Spring
- 3 El método no es público.
- 4 Problema de autollamada
- 5 La fuente de datos no tiene configurado un administrador de transacciones
- 6 transacciones no son compatibles
- 7 Se comió anormal
- 8 Error de tipo de excepción
- 9 La excepción ocurrió en el hilo recién creado.
1 El motor de base de datos no admite transacciones.
Las transacciones de Spring son transacciones de la capa empresarial y su capa inferior aún depende del soporte de transacciones de la propia base de datos. Tomando MySQL como ejemplo, su motor MyISAM no admite operaciones de transacciones, InnoDB es el motor que admite transacciones, InnoDB se usa generalmente para admitir transacciones.
2 clases no son administradas por Spring
Como se muestra en el siguiente ejemplo:
//@Service
public class OrderServiceImpl implements OrderService {
@Transactional
public void updateOrder(Order order) {
// 业务逻辑
}
}
Si comenta la anotación en este momento @Service
, esta clase no se cargará en un Bean, entonces esta clase no se Spring
administrará y la transacción no será válida.
3 El método no es público.
@Transactional
Solo se puede usar public
en métodos; de lo contrario, la transacción no se invalidará. Si desea usarlo en otros public
métodos, puede activar AspectJ
el modo proxy.
4 Problema de autollamada
Ejemplo 1:
@Service
public class OrderServiceImpl implements OrderService {
public void update(Order order) {
updateOrder(order);
}
@Transactional
public void updateOrder(Order order) {
// 业务逻辑
}
}
update
No hay anotaciones en el método @Transactional
, llame @Transactional
al método anotado updateOrder
y updateOrder
agregue una transacción al método.
Ejemplo 2:
@Service
public class OrderServiceImpl implements OrderService {
@Transactional
public void update(Order order) {
updateOrder(order);
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void updateOrder(Order order) {
// 业务逻辑
}
}
En el Ejemplo 2 , update
se agrega el método y se abre una nueva transacción.@Transactional
updateOrder
REQUIRES_NEW
En los dos ejemplos anteriores, las transacciones no tendrán efecto porque se llaman a sí mismas, es decir, llamar al método propio de la clase sin pasar por la clase proxy de Spring. De forma predeterminada, la transacción solo tendrá efecto cuando se llame externamente.
5 La fuente de datos no tiene configurado un administrador de transacciones
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
Como se muestra arriba, incluso si se usa la función de administración de transacciones de Spring en el código, si el administrador de transacciones de Spring no está configurado en el proyecto, la transacción de Spring no tendrá efecto.
6 transacciones no son compatibles
propagation
Error de configuración del comportamiento de propagación de transacciones
Ejemplo:
@Service
public class OrderServiceImpl implements OrderService {
@Transactional
public void update(Order order) {
updateOrder(order);
}
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void updateOrder(Order order) {
// 业务逻辑
}
}
Propagation.NOT_SUPPORTED
: Indica que no se ejecutará como una transacción y, si actualmente hay una transacción, se suspenderá.
Si Propagatio
n está configurado para no admitir la ejecución en modo de transacción, la transacción no tendrá efecto.
7 Se comió anormal
Ejemplo:
@Service
public class OrderServiceImpl implements OrderService {
@Transactional
public void updateOrder(Order order) {
try {
// 业务代码
} catch {
}
}
}
Si come la excepción y luego no la descarta, ¡la transacción no se revertirá!
8 Error de tipo de excepción
Ejemplo:
@Service
public class OrderServiceImpl implements OrderService {
@Transactional
public void updateOrder(Order order) {
try {
// 业务代码
} catch {
throw new Exception("更新错误");
}
}
}
Esta transacción no tendrá efecto porque la reversión predeterminada es: RuntimeException
Si desea activar la reversión de otras excepciones, debe configurarla en la anotación, como por ejemplo:
@Transactional(rollbackFor = Exception.class)
Esta configuración se limita a la clase de excepción Throwable y sus subclases.
9 La excepción ocurrió en el hilo recién creado.
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
@Autowired
private RoleService roleService;
@Transactional
public void add(UserModel userModel) throws Exception {
userMapper.insertUser(userModel);
new Thread(() -> {
// 此处发生异常
roleService.save();
}).start();
}
}
@Service
public class RoleService {
@Transactional
public void save() {
// 保存数据
}
}
Podemos ver que en el método de transacción agregar, se llama al método de transacción guardar, pero el método de transacción guardar se llama en otro hilo. Esto dará como resultado que los dos métodos no estén en el mismo subproceso y obtengan conexiones de bases de datos diferentes, lo que dará como resultado dos transacciones diferentes. Si se produce una excepción en el método de guardar, es imposible revertir el método de agregar.