spring 为什么在这个方法中忽略了@ translation注解?

igetnqfo  于 2024-01-05  发布在  Spring
关注(0)|答案(2)|浏览(338)

我在尝试将@ translation注解应用于同一个类(MyService)中的方法(methodC())时遇到了这个问题。尽管使用了注解,事务似乎没有按预期创建。

  1. @Service
  2. public class MyService {
  3. @Autowired
  4. private Service1 service1;
  5. @Autowired
  6. private Service2 service2;
  7. @Override
  8. public void methodA() {
  9. methodB();
  10. }
  11. private void methodB() {
  12. try{
  13. methodC();
  14. }catch(MyException e){
  15. System.out.println(e);
  16. }catch(Exception e){
  17. System.out.println(e);
  18. }
  19. }
  20. @Transactional
  21. public void methodC() throws MyException, Exception{
  22. try{
  23. service1.someDeleteAndInserts();
  24. service2.someDeleteAndInserts();
  25. }catch(MyException e){
  26. throw e;
  27. }catch(Exception e){
  28. throw e;
  29. }
  30. }
  31. }

字符串
就像我现在所做的,它为每个方法单独创建一个事务,我希望它只为该方法中调用的所有方法创建一个事务。

  1. @Transactional
  2. public void methodC() throws MyException, Exception{
  3. try{
  4. service1.someDeleteAndInserts();
  5. service2.someDeleteAndInserts();
  6. }catch(MyException e){
  7. throw e;
  8. }catch(Exception e){
  9. throw e;
  10. }
  11. }

o4hqfura

o4hqfura1#

你不能在同一个服务中调用带@Transactional注解的方法。你只能从服务外部调用它,否则不会创建任何transaction。每个spring服务都是一个代理,transactions(AOP)是在代理上创建的,所以一旦你输入任何方法,你就不再在代理中了,所以没有AOP(没有transactions)。
注意事项:但是你可以把@Transactional放在methodA()上来创建一个transaction,但是transaction会在你调用它的时候就开始,而不是在它到达methodC的时候,而且任何transaction异常都会传播到你调用methodA()的地方,而不是methodC()
例如,如果您有:

  1. @Service
  2. public class Service1 {
  3. @Transactional
  4. public void method1() { ... }
  5. public void method2() {
  6. method1();
  7. }
  8. }
  9. @Service
  10. public class Service2 {
  11. @Autowired
  12. private Service1 service1;
  13. public void method1() {
  14. service1.method1();
  15. }
  16. public void method2() {
  17. service1.method2();
  18. }
  19. }

字符串

  • 调用service1.method2()创建事务。
  • 调用service1.method1()将创建一个。
  • 调用service2.method2()创建事务。
  • 调用service2.method1()将创建一个。

因为Spring处理代理和AOP的方式。

展开查看全部
hvvq6cgz

hvvq6cgz2#

正如其他的答案和评论所指出的,你必须跨代理边界调用它才能工作,这同样适用于其他注解,比如@Cacheable
有一个小技巧可以让它工作,那就是将服务的一个示例自动装配到它自己中,并在注入的版本上调用该方法。

  1. @Service
  2. // 1. Set the proxy mode to TARGET_CLASS
  3. @Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
  4. public class MyService {
  5. // 2. Autowire an instance of the service into itself
  6. @Autowired
  7. private MyService self;
  8. private void methodB() {
  9. try{
  10. // 3. Call methodC through your injected version
  11. self.methodC();
  12. }catch(MyException e){
  13. System.out.println(e);
  14. }catch(Exception e){
  15. System.out.println(e);
  16. }
  17. }
  18. }

字符串
现在,当您使用注入的服务调用methodC时,它将参与事务。

展开查看全部

相关问题