1. O mecanismo de banco de dados não suporta transações
. Tome o MySQL como exemplo. Seu mecanismo MyISAM não suporta operações de transação. InnoDB é o mecanismo que suporta transações. Geralmente, InnoDB é usado para suportar transações.
2. Não é gerenciado pelo Spring .
// @Service
public class OrderServiceImpl implements OrderService {
@Transactional
public void updateOrder(Order order) {
// update order
}
}
Se a
anotação @Service for comentada neste momento , esta classe não será carregada como um Bean, então esta classe não será gerenciada pelo Spring e a transação se tornará naturalmente inválida
3. O método não é público, o que
provavelmente significa que
@Transactional só pode ser usado para métodos públicos, caso contrário, a transação não falhará. Se você quiser usá-lo para métodos não públicos, pode ativar o
modo proxy AspectJ.
4. Problema de auto-chamada
Vejamos dois exemplos:
@Service
public class OrderServiceImpl implements OrderService {
public void update(Order order) {
updateOrder(order);
}
@Transactional
public void updateOrder(Order order) {
// update order
}
}
Não há anotação @Transactional no método de atualização, e o método updateOrder com anotação @Transactional é chamado. A transação no método updateOrder funciona?
Vejamos o seguinte exemplo novamente:
@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
}
}
Desta vez, @Transactional é adicionado ao método de atualização e REQUIRES_NEW é adicionado a updateOrder para iniciar uma nova transação. A transação recém-aberta funcionará?
A resposta a esses dois exemplos é: não funciona!
Como eles chamam seus próprios métodos, eles chamam seus próprios métodos em vez das classes proxy do Spring.Por padrão, a transação só terá efeito quando a transação for chamada externamente.Este também é um problema clássico, frequentemente falado.
Solução:
@Resource
private UpdateOrder updateOrder;
public void update(Order order) {
updateOrder.updateOrder(order);
}
Este é o mesmo que spring @Sync requer geração de proxy
https://www.cnblogs.com/jtlgb/p/11124770.html
5. A fonte de dados não tem um gerenciador de transações configurado
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
6, não suporta assuntos
@Transactional(propagation = Propagation.NOT_SUPPORTED)
7. Se a exceção for comida,
tente pegar não lançará uma exceção.Se a exceção for comida e não for lançada, como a transação pode ser revertida!
8. O tipo de exceção está errado
@Transactional
public void updateOrder(Order order)
Esta transação também não é efetiva, porque o rollback padrão é: RuntimeException, se você deseja acionar o rollback de outras exceções, você precisa configurá-lo na anotação, como:
@Transactional(rollbackFor = Exception.class)
Essa configuração é limitada à classe de exceção Throwable e suas subclasses.
Referência: https://zhuanlan.zhihu.com/p/101396825