La llamada al método Spring @Transaction por el método dentro de la misma clase, ¿no funciona?

Soy nuevo en Spring Transaction. Algo que encontré realmente extraño, probablemente entendí esto correctamente. Quería tener un nivel de método transaccional y tengo un método de llamada dentro de la misma clase y parece que no le gusta, tiene que ser llamado desde la clase separada. No entiendo cómo es eso posible. Si alguien tiene una idea de cómo resolver este problema, lo agradecería enormemente. Me gustaría utilizar la misma clase para llamar al método transaccional anotado.

Aquí está el código:

public class UserService { @Transactional public boolean addUser(String userName, String password) { try { // call DAO layer and adds to database. } catch (Throwable e) { TransactionAspectSupport.currentTransactionStatus() .setRollbackOnly(); } } public boolean addUsers(List users) { for (User user : users) { addUser(user.getUserName, user.getPassword); } } } 

Es una limitación de Spring AOP (objetos dynamics y cglib ).

Si configura Spring para usar AspectJ para manejar las transacciones, su código funcionará.

La mejor y más sencilla alternativa es refactorizar tu código. Por ejemplo, una clase que maneja usuarios y otra que procesa a cada usuario. Entonces el manejo predeterminado de las transacciones con Spring AOP funcionará.


Consejos de configuración para manejar transacciones con AspectJ

Para permitir que Spring use AspectJ para las transacciones, debe establecer el modo en AspectJ:

  

Si está utilizando Spring con una versión anterior a la 3.0, también debe agregar esto a su configuración de Spring:

    

El problema aquí es que los proxies AOP de Spring no se extienden sino que envuelven su instancia de servicio para interceptar llamadas. Esto tiene el efecto de que cualquier llamada a “esto” desde su instancia de servicio se invoca directamente en esa instancia y no puede ser interceptada por el proxy de envoltura (el proxy ni siquiera es consciente de dicha llamada). Una solución ya se menciona. Otro ingenioso sería simplemente hacer que Spring inserte una instancia del servicio en el servicio mismo, y llame a su método en la instancia inyectada, que será el proxy que maneja sus transacciones. Pero tenga en cuenta que esto puede tener efectos secundarios negativos también, si su servicio bean no es un singleton:

   ...  public class UserService { private UserService self; public void setSelf(UserService self) { this.self = self; } @Transactional public boolean addUser(String userName, String password) { try { // call DAO layer and adds to database. } catch (Throwable e) { TransactionAspectSupport.currentTransactionStatus() .setRollbackOnly(); } } public boolean addUsers(List users) { for (User user : users) { self.addUser(user.getUserName, user.getPassword); } } } 

Esta es mi solución para la auto invocación :

 private SBMWSBL self; @Autowired private ApplicationContext applicationContext; @PostConstruct public void postContruct(){ self = applicationContext.getBean(SBMWSBL.class); } 

Con Spring 4, es posible Autoconexionarse

 @Service @Transactional public class UserServiceImpl implements UserService{ @Autowired private UserRepositroy repositroy; @Autowired private UserService userService; @Override public void update(int id){ repository.findOne(id).setName("ddd"); } @Override public void save(Users user) { repositroy.save(user); userService.update(1)l } } 

Puede autoenlazar BeanFactory dentro de la misma clase y hacer una

getBean(YourClazz.class)

Automatizará automáticamente tu clase y tendrá en cuenta tu @Transactional u otra anotación aop.

El problema está relacionado con cómo las clases de carga de spring y los proxies. No funcionará, hasta que escriba su método / transacción interna en otra clase o vaya a otra clase y luego vuelva a su clase y luego escriba el método de transcation interno nested.

En resumen, los proxies de spring no permiten los escenarios a los que se enfrenta. tienes que escribir el segundo método de transacción en otra clase