Estou com um problema com o Spring 3.1 com a anotação @Transational
No primeiro caso, que é o que eu gostaria que funcionasse fica assim:
ele faz o persist normalmente no metodo2, mas não executa a procedure
@Service
public class Service{
@Autowired
private Dao dao;
@Transational
public void metodo(String asdf){
metodo2(asdf);
metodo3(asdf);
}
private void metodo2(String asdf){
dao.save(asdf);
}
private void metodo3(String asdf){
dao.callProcedure(asdf);
}
}
@Repository
public class Dao{
public void save(String asdf){
// Implementacao
}
public void callProcedure(){
// Implementacao
}
}
E no segundo caso, mudo o @Transational para o Dao, e os 2 metodos são executados normalmente, porem gostaria de deixar no @Transational na camada de services:
@Service
public class Service{
@Autowired
private Dao dao;
public void metodo(String asdf){
metodo2(asdf);
metodo3(asdf);
}
private void metodo2(String asdf){
dao.save(asdf);
}
private void metodo3(String asdf){
dao.callProcedure(asdf);
}
}
@Repository
public class Dao{
@Transational
public void save(String asdf){
// Implementacao
}
@Transational
public void callProcedure(){
// Implementacao
}
}
Alguem sabe pq isso acontece?
@Service
@Transational
public class Service{
@Autowired
private Dao dao;
public void metodo(String asdf){ ...}
.....
fica a dica
fallow
Anotando a classe com @Transational, o comportamento ficou igual ao caso 1,
ele salva em uma tabela X, mas não executa a procedure…
SOLUÇÃO
Lendo a documentacao http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/transaction.html#transaction-declarative-annotations
vi que além de não executar em métodos não public, tbm não executado qnd chamado por um metodo da mesma classe
In proxy mode (which is the default), only external method calls coming in through the proxy are intercepted. This means that self-invocation, in effect, a method within the target object calling another method of the target object, will not lead to an actual transaction at runtime even if the invoked method is marked with @Transactional.
Consider the use of AspectJ mode (see mode attribute in table below) if you expect self-invocations to be wrapped with transactions as well. In this case, there will not be a proxy in the first place; instead, the target class will be weaved (that is, its byte code will be modified) in order to turn @Transactional into runtime behavior on any kind of method.
Modifiquei as configurações do spring
<context:load-time-weaver/>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="false" mode="aspectj"/>
e o codigo ficou assim:
@Service
public class Service{
@Autowired
private Dao dao;
public void metodo(String asdf){
metodo2(asdf);
metodo3(asdf);
}
@Transational
private void metodo2(String asdf){
dao.save(asdf);
}
@Transational
private void metodo3(String asdf){
dao.callProcedure(asdf);
}
}
@Repository
public class Dao{
public void save(String asdf){
// Implementacao
}
public void callProcedure(){
// Implementacao
}
}