O motivo da falha da transação de primavera (invocando sua própria solução de motivo)

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

Acho que você gosta

Origin blog.csdn.net/qq_38893133/article/details/110819461
Recomendado
Clasificación