Art*_*nov 9 java spring scheduled-tasks spring-transactions spring-boot
我有一个问题:为什么当我们使用@Scheduled
and 注释方法时@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() {
}
}
Run Code Online (Sandbox Code Playgroud)
我有两个解决这个问题的方法:
从Scheduled
方法调用代理.
用代理ConcurrentTaskScheduler
对象实现和替换ScheduledMethodRunnable
(与我的类一起)的对象ScheduledMethodRunnable
.
但是这种解决方案非常不方便.
你能解释一下为什么会@Scheduled
这样吗?
谢谢!
发生这种情况是因为使用了 MAGIC 来处理这两个注释。
我想有几件事会发生:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
我个人推荐第二种方法。