java - 从另一个线程调用@Transactional 方法(可运行)

标签 java spring runnable

是否有任何简单的解决方案可以在新线程中使用 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/

相关文章:

java - 使用 Spring Security 保护应用程序不起作用

java - Spring在SecurityContextHolder中获取自定义UserDetails

java - 将哈希表保存在持久存储中

java - 除了 SVN,您如何管理您的开发、测试和生产源代码?

java - 为什么我无法将类导入到 Eclipse Maven 项目中的 java 文件中?

java - OSGi 线程永远不会停止运行,为线程定义了固定的生命周期

java - Java在一定时间内创建多个线程

java - 计算时间线程android

java - Apache NiFi - NullPointerException 在自定义处理器上设置多个线程

java - 在 Java 并行/多线程中创建现有代码