为什么@Scheduled注释不能与@Transaction注释一起使用.春季靴 [英] Why @Scheduled annotation doesn't work with @Transaction annotation. Spring Boot

查看:1960
本文介绍了为什么@Scheduled注释不能与@Transaction注释一起使用.春季靴的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个问题: 为什么当我们用@Scheduled@Transaction注释方法时,事务不起作用? 我知道@Scheduled调用我的类,而不是Spring创建的代理类,但是无法理解这种行为.

I have a question: Why when we annotate method with @Scheduled and @Transaction, transaction doesn't work? I know that the @Scheduled call my class instead of proxy class that created by Spring, but can't understand this behavior.

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserServiceImpl implements UserService {

    @Override
    @Scheduled(fixedRateString = "${somestring}",initialDelayString = "${anotherstring}")
    @Transactional
    public void doSomething() {

        }
    }

我对此问题有两种解决方案:

I have two solutions of this problem:

  1. Scheduled方法调用代理.

实施ConcurrentTaskScheduler 并替换ScheduledMethodRunnable的对象(与我的课程相同) 带有ScheduledMethodRunnable对象和代理.

Implement ConcurrentTaskScheduler and replace object of ScheduledMethodRunnable(that is with my class) with object of ScheduledMethodRunnable with proxy.

但是这种解决方案非常不方便.

But this solutions is very inconvenient.

您能解释为什么@Scheduled如此工作吗?

Can you explaim me why @Scheduled works like this?

谢谢!

推荐答案

发生这种情况是因为要同时处理两个注释,并且使用了MAGIC.

It happens because to process both annotations MAGIC is used.

我想发生了几件事:

  1. UserServiceImpl已创建.
  2. 处理
  3. @Scheduled批注,并存储对bean的引用以在适当的时候调用它.
  4. @Transactional批注已处理.它创建代理,该代理存储对原始bean的引用.原始bean被替换为应用程序上下文中的代理.
  1. UserServiceImpl is created.
  2. @Scheduled annotation is processed and reference to bean is stored to invoke it at appropriate time.
  3. @Transactional annotation is processed. It create proxy which store reference to original bean. Original bean is replaced to proxy in application context.

如果第2步和第3步以不同的顺序通过,那么您就没问题了.

If step 2 and 3 passed in different order then you had no problem.

我不知道如何控制注释的处理顺序.我什至不知道有没有可能.

I don't know how to control order in which annotation is processed. I don't even sure it is possible at all.

基本上有两个解决方案.

  1. 使用另一种魔法来处理@Transaction.默认方法是创建代理对象,但可以指示Spring检测当前类.
  2. 将其拆分为两个类,每个类都将具有仅带有一个注释的方法.
  1. Use different kind of magic to process @Transaction. Default way is to create proxy object, but it is possible to instruct Spring to instrument current class.
  2. Split this to two class each of them will have method with only one annotation.

示例:

@Service
public class UserServiceImpl implements UserService {

    @Override
    @Transactional
    public void doSomething() {

    }
}

@Service
public class UserServiceScheduler {

    @Inject
    private UserService service;

    @Scheduled(fixedRateString = "${somestring}",initialDelayString = "${anotherstring}")
    public void doSomething() {
         service.doSomething();
    }
}

我个人建议第二种方法.

I'm personally recommend second approach.

这篇关于为什么@Scheduled注释不能与@Transaction注释一起使用.春季靴的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆