Java Spring@scheduled方法未通过代理调用,因此没有事务
我使用的是Spring 3.2.13.RELEASE,我有一个方法(在Spring托管bean上)用@Scheduled注释,该方法运行但未通过代理调用,因此在我尝试访问事务时失败:Java Spring@scheduled方法未通过代理调用,因此没有事务,java,spring,scheduled-tasks,Java,Spring,Scheduled Tasks,我使用的是Spring 3.2.13.RELEASE,我有一个方法(在Spring托管bean上)用@Scheduled注释,该方法运行但未通过代理调用,因此在我尝试访问事务时失败: @Service @Transactional public class CoreEmailServiceImpl extends BaseEmailServiceImpl implements CoreEmailService { @Override @Transactional @Sc
@Service
@Transactional
public class CoreEmailServiceImpl extends BaseEmailServiceImpl implements CoreEmailService {
@Override
@Transactional
@Scheduled(cron = "0 0 5 * * *")
public void sendDailySummaryEmail() {
//.. stuff
TransactionSynchronizationManager.registerSynchronization(...); // fails
}
}
堆栈跟踪:
[#|2016-02-03T05:00:00.386-0700|SEVERE|glassfish3.1.2|com.a.b.common.CoreEmailServiceImpl|_ThreadID=22570;_ThreadName=Thread-2;|Error sending email.
java.lang.IllegalStateException: Transaction synchronization is not active
at org.springframework.transaction.support.TransactionSynchronizationManager.registerSynchronization(TransactionSynchronizationManager.java:291)
at com.a.b.common.BaseEmailServiceImpl.sendEmail(BaseEmailServiceImpl.java:144)
at com.a.b.common.BaseEmailServiceImpl.sendEmail(BaseEmailServiceImpl.java:95)
at com.a.b.common.CoreEmailServiceImpl.sendDailySummaryEmail(CoreEmailServiceImpl.java:95)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:64)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:53)
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:178)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:292)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
但当我通过SpringMVC端点调用该方法时,它工作正常
@Controller
@RequestMapping("/admin")
public class AdminController extends AbstractController {
@RequestMapping(value = "/job/daily-summary", method = RequestMethod.POST, produces = "application/json")
@Autowired
private AdminService adminService;
@ResponseBody
public ResponseBean runDailySummaryEmailJob() {
adminService.runDailySummaryEmailJob();
return null;
}
}
@Service
@Transactional(readOnly = true)
public class AdminServiceImpl extends DefaultServiceImpl implements AdminService {
@Autowired
private CoreEmailService coreEmailService;
@Override
public void runDailySummaryEmailJob() {
coreEmailService.sendDailySummaryEmail();
}
}
在我的项目的一个完全不相关的部分中,我在spring托管bean上有另一个通过代理调用的调度方法。两个堆栈跟踪中的以下几行实际上概述了我所看到的两个调度方法之间的不一致性,这两个方法都驻留在spring托管bean上:
com.a.b.common.CoreEmailServiceImpl.sendDailySummaryEmail(CoreEmailServiceImpl.java:93)
com.sun.proxy.$Proxy679.emailMonthlyAccountStatement(未知来源)
ScheduledAnnotationBeanPostProcessor
通过AopUtils.isjdDynamicProxy(bean)
检查调度方法是否属于代理,我已经确认,除此之外的所有其他调度方法都返回true。现在我想知道为什么
编辑:在初始化期间,我可以确认
DefaultAopProxyFactory
确实拾取了CoreEmailServiceImpl
并为其创建了动态代理。仍然不确定为什么ScheduledAnnotationBeanPostProcessor
没有检测到此代理。我尝试将spring更新到3.2.16,以查看SPR-12709是否有任何效果,但没有帮助。听起来像这里描述的代理可能有问题:这个答案意味着预期的行为是以本机方式调用计划的方法这取决于我在该方法中调用我的代理。我找不到关于此的任何文档,而且我刚刚编辑了我的原始帖子,声明我的项目的另一部分有一个通过代理调用的计划方法。我尝试将spring更新到3.2.16,以查看SPR-12709是否有任何效果,但没有帮助。听起来可能是代理的问题,如这里所述:这个答案意味着预期的行为是以本机方式调用计划的方法,并且由我在该方法中调用我的代理。我找不到关于这个的任何文档,而且我刚刚编辑了我的原始帖子,声明我的项目的另一部分有一个通过代理调用的预定方法。