是否有任何简单的解决方案可以在新线程中使用 JPA 将数据保存到数据库中?
我的基于 Spring 的 Web 应用程序允许用户管理计划任务。在运行时,他可以创建和启动预定义任务的新实例。我正在使用 spring 的 TaskScheduler 并且一切正常。
但我需要将每个触发任务的 boolean 结果保存到数据库中。我该怎么做?
编辑: 我必须概括我的问题:我需要从任务中调用我的 @Service 类的方法。因为任务结果必须在保存到数据库之前“处理”。
编辑 2: 我有问题的代码的简化版本在这里。从调度程序调用 saveTaskResult() 时,会打印出消息,但不会将任何内容保存到数据库中。但是每当我从 Controller 调用 saveTaskResult() 时,记录都会正确保存到数据库中。
@Service
public class DemoService {
@Autowired
private TaskResultDao taskResultDao;
@Autowired
private TaskScheduler scheduler;
public void scheduleNewTask() {
scheduler.scheduleWithFixedDelay(new Runnable() {
public void run() {
// do some action here
saveTaskResult(new TaskResult("result"));
}
}, 1000L);
}
@Transactional
public void saveTaskResult(TaskResult result) {
System.out.println("saving task result");
taskResultDao.persist(result);
}
}
最佳答案
您的代码的问题是您希望在调用 saveTaskResult()
时启动事务。这不会发生,因为 Spring 使用 AOP 来启动和停止事务。
如果您从 bean 工厂或通过依赖注入(inject)获得事务性 Spring bean 的实例,那么您获得的实际上是 bean 周围的代理。此代理在调用实际方法之前启动事务,并在方法完成后提交或回滚事务。
在这种情况下,您调用 bean 的本地方法,而不通过事务代理。将 saveTaskResult()
方法(使用 @Transactional
注释)放在另一个 Spring bean 中。将这个另一个Spring bean注入(inject)到DemoService中,然后从DemoService中调用另一个Spring bean,一切都会好起来的。
关于java - 从另一个线程调用@Transactional 方法(可运行),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11275471/