首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么@调度注释不能与@Transaction注释一起工作。Spring Boot

为什么@调度注释不能与@Transaction注释一起工作。Spring Boot
EN

Stack Overflow用户
提问于 2017-07-27 15:52:21
回答 2查看 9.5K关注 0票数 13

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

代码语言:javascript
运行
复制
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() {

        }
    }

我有两种解决这个问题的方法:

  1. Scheduled方法调用代理。
  2. 实现ConcurrentTaskScheduler,并将ScheduledMethodRunnable的对象(即我的类)替换为代理的ScheduledMethodRunnable对象。

但是这个解决方案很不方便。

你能解释一下为什么@Scheduled会这样工作吗?

谢谢!

EN

Stack Overflow用户

发布于 2017-07-27 16:18:54

之所以会发生这种情况,是因为为了处理这两个注释,都使用了魔术。

我想有几件事发生了:

  1. 创建了UserServiceImpl
  2. @Scheduled注释进行处理,并存储对bean的引用,以便在适当的时间调用它。
  3. @Transactional注释进行处理。它创建代理来存储对原始bean的引用。在应用程序上下文中将原始bean替换为代理。

如果步骤2和步骤3以不同的顺序传递,那么您就没有问题。

我不知道如何控制处理注释的顺序。我甚至不确定这是可能的。

基本上有两个解决方案

  1. 使用不同的魔法来处理@Transaction。默认方法是创建代理对象,但可以指示Spring检测当前类。
  2. 将其拆分为两个类,每个类都有一个注释的方法。

示例:

代码语言:javascript
运行
复制
@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();
    }
}

我个人推荐第二种方法。

票数 3
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45355601

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档