A questão não é privada ou pública, a questão é: como é invocada e qual implementação de AOP você usa!
Se você usar o Spring Proxy AOP (padrão), todas as funcionalidades do AOP fornecidas pelo Spring (como @Transational
) serão consideradas apenas se a chamada passar pelo proxy. - Normalmente, este é o caso se o método anotado for chamado de outro bean.
Isso tem duas implicações:
- Como os métodos privados não devem ser invocados a partir de outro bean (a exceção é reflexão), suas
@Transactional
Anotações não são levadas em consideração.
- Se o método for público, mas for invocado a partir do mesmo bean, ele também não será levado em consideração (esta instrução estará correta apenas se for usado o Spring Proxy AOP (padrão)).
Consulte a Referência do Spring: Capítulo 9.6 9.6 Mecanismos de proxy
IMHO, você deve usar o modo aspectJ, em vez dos Spring Proxies, que resolverão o problema. E os Aspectos Transacionais AspectJ são tecidos até em métodos privados (verificados no Spring 3.0).
A resposta da sua pergunta é não - não
@Transactional
terá efeito se usada para anotar métodos privados. O gerador de proxy os ignorará.Isso está documentado no capítulo 10.5.6 do Manual da Primavera :
fonte
Por padrão, o
@Transactional
atributo funciona apenas ao chamar um método anotado em uma referência obtida do applicationContext.Isso abrirá uma transação:
Isto não irá:
Referência da Primavera: Usando @Transactional
fonte
Sim, é possível usar o @Transactional em métodos privados, mas, como outros usuários mencionaram, isso não funcionará imediatamente. Você precisa usar o AspectJ. Levei algum tempo para descobrir como fazê-lo funcionar. Vou compartilhar meus resultados.
Eu escolhi usar a tecelagem em tempo de compilação em vez da tecelagem em tempo de carga porque acho que é uma opção melhor em geral. Além disso, estou usando o Java 8, portanto, pode ser necessário ajustar alguns parâmetros.
Primeiro, adicione a dependência para aspectjrt.
Em seguida, adicione o plug-in AspectJ para fazer a tecelagem de bytecode real no Maven (este pode não ser um exemplo mínimo).
Por fim, adicione isso à sua classe de configuração
Agora você deve poder usar o @Transactional em métodos privados.
Uma ressalva a esta abordagem: você precisará configurar seu IDE para conhecer o AspectJ, caso contrário, se você executar o aplicativo via Eclipse, por exemplo, ele poderá não funcionar. Teste contra uma compilação direta do Maven como uma verificação de sanidade.
fonte
Se você precisar agrupar um método privado dentro de uma transação e não quiser usar o aspectj, poderá usar o TransactionTemplate .
fonte
TransactionTemplate
uso, mas chame esse segundo método em..RequiresTransaction
vez de..InTransaction
. Sempre nomeie as coisas como gostaria de lê-las um ano depois. Também argumentaria para pensar se ele realmente requer um segundo método privado: coloque seu conteúdo diretamente naexecute
implementação anônima ou se isso ficar confuso, pode ser uma indicação para dividir a implementação em outro serviço que você pode anotar@Transactional
.Os documentos do Spring explicam que
Outra maneira é o usuário BeanSelfAware
fonte
BeanSelfAware
? Ele não se parece com a classe de um PrimaveraA resposta é não. Consulte a Referência da Primavera: Usando @Transactional :
fonte
Da mesma maneira que @loonis sugeriu usar o TransactionTemplate, um pode usar este componente auxiliar (Kotlin):
Uso:
Não sei se
TransactionTemplate
reutilizará a transação existente ou não, mas esse código definitivamente o faz.fonte