1. El motor de la base de datos no admite transacciones
. Tome MySQL como ejemplo. Su motor MyISAM no admite operaciones de transacción. InnoDB es el motor que admite transacciones. Generalmente, InnoDB se utiliza para admitir transacciones.
2. No está administrado por Spring .
// @Service
public class OrderServiceImpl implements OrderService {
@Transactional
public void updateOrder(Order order) {
// update order
}
}
Si la
anotación @Service está comentada en este momento , esta clase no se cargará como un Bean, entonces esta clase no será administrada por Spring y la transacción naturalmente dejará de ser válida.
3. El método no es público, lo cual
probablemente significa que
@Transactional solo puede Se usa para métodos públicos, de lo contrario la transacción no fallará. Si desea usarlo para métodos no públicos, puede habilitar el
modo proxy de AspectJ.
4. Problema de auto-llamada
Veamos dos ejemplos:
@Service
public class OrderServiceImpl implements OrderService {
public void update(Order order) {
updateOrder(order);
}
@Transactional
public void updateOrder(Order order) {
// update order
}
}
No hay una anotación @Transactional en el método de actualización, y se llama al método updateOrder con la anotación @Transactional. ¿Funciona la transacción en el método updateOrder?
Veamos de nuevo el siguiente ejemplo:
@Service
public class OrderServiceImpl implements OrderService {
@Transactional
public void update(Order order) {
updateOrder(order);
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void updateOrder(Order order) {
// update order
}
}
Esta vez, @Transactional se agrega al método de actualización y REQUIRES_NEW se agrega a updateOrder para iniciar una nueva transacción. ¿Funcionará la transacción recién abierta?
La respuesta a estos dos ejemplos es: ¡no funciona!
Debido a que llaman a sus propios métodos, llaman a sus propios métodos en lugar de las clases proxy de Spring. De forma predeterminada, la transacción solo tendrá efecto cuando la transacción se llame externamente. Este también es un problema clásico del que se habla a menudo.
Solución:
@Resource
private UpdateOrder updateOrder;
public void update(Order order) {
updateOrder.updateOrder(order);
}
Esto es lo mismo que Spring @Sync requiere generación de proxy
https://www.cnblogs.com/jtlgb/p/11124770.html
5. La fuente de datos no tiene un administrador de transacciones configurado
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
6, no admite asuntos
@Transactional(propagation = Propagation.NOT_SUPPORTED)
7. Si se come la excepción,
try catch no lanza una excepción Si la excepción se come y luego no se lanza, ¿cómo se puede revertir la transacción?
8. El tipo de excepción es incorrecto.
@Transactional
public void updateOrder(Order order)
Esta transacción tampoco es efectiva, porque la reversión predeterminada es: RuntimeException, si desea activar la reversión de otras excepciones, debe configurarla en la anotación, como:
@Transactional(rollbackFor = Exception.class)
Esta configuración está limitada a la clase de excepción Throwable y sus subclases.
Referencia: https://zhuanlan.zhihu.com/p/101396825