我有一个问题:为什么当我们用@Scheduled
和@Transaction
注释方法时,事务不能工作?我知道@Scheduled
调用了我的类,而不是由Spring创建的代理类,但是不能理解这种行为。
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() {
}
}
我有两种解决这个问题的方法:
Scheduled
方法调用代理。ConcurrentTaskScheduler
,并将ScheduledMethodRunnable
的对象(即我的类)替换为代理的ScheduledMethodRunnable
对象。但是这个解决方案很不方便。
你能解释一下为什么@Scheduled
会这样工作吗?
谢谢!
发布于 2017-07-27 16:18:54
之所以会发生这种情况,是因为为了处理这两个注释,都使用了魔术。
我想有几件事发生了:
UserServiceImpl
。@Scheduled
注释进行处理,并存储对bean的引用,以便在适当的时间调用它。@Transactional
注释进行处理。它创建代理来存储对原始bean的引用。在应用程序上下文中将原始bean替换为代理。如果步骤2和步骤3以不同的顺序传递,那么您就没有问题。
我不知道如何控制处理注释的顺序。我甚至不确定这是可能的。
基本上有两个解决方案。
@Transaction
。默认方法是创建代理对象,但可以指示Spring
检测当前类。示例:
@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();
}
}
我个人推荐第二种方法。
https://stackoverflow.com/questions/45355601
复制相似问题