20

是否有任何简单的解决方案可以在新线程中使用 JPA 将数据保存到数据库中?

我的基于 Spring 的 Web 应用程序允许用户管理计划任务。在运行时,他可以创建和启动预定义任务的新实例。我正在使用spring的TaskScheduler,一切正常。

但是我需要将每个触发任务的布尔结果保存到数据库中。我怎样才能做到这一点?

编辑:我必须概括我的问题:我需要从任务中调用我的@Service 类的方法。因为任务结果必须在保存到数据库之前“处理”。

编辑 2:我有问题的代码的简化版本在这里。从调度程序调用 saveTaskResult() 时,会打印出消息,但不会将任何内容保存到数据库中。但是每当我从控制器调用 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);
    }

}
4

3 回答 3

34

您的代码的问题是您希望在调用saveTaskResult(). 这不会发生,因为 Spring 使用 AOP 来启动和停止事务。

如果您从 bean 工厂或通过依赖注入获得事务性 Spring bean 的实例,那么您获得的实际上是 bean 周围的代理。此代理在调用实际方法之前启动事务,并在方法完成后提交或回滚事务。

在这种情况下,您调用 bean 的本地方法,而不通过事务代理。将saveTaskResult()方法(用 注释@Transactional)放在另一个 Spring bean 中。将这个另一个 Spring bean 注入到 DemoService 中,并从 DemoService 中调用另一个 Spring bean,一切都会好起来的。

于 2012-06-30T21:08:18.557 回答
4

事务保存在线程本地存储中。
如果您的其他方法正在运行带有@Transactional注释的线程。
默认设置为REQUIRED,这意味着如果您@Transacitonal从不同的线程运行带有注释的方法,您将拥有一个新事务(因为该线程的线程本地存储中没有事务)。

于 2012-06-30T17:36:36.597 回答
0

另一种选择(除了在其中使用 @Transactional 方法创建单独的 Spring Bean 之外)是使用TransactionTemplate.

final TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
   taskExecutor.execute(new Runnable() {
        @Override
        public void run() {
            transactionTemplate.execute(new TransactionCallbackWithoutResult() {
                @Override
                protected void doInTransactionWithoutResult(TransactionStatus status) {
                   dao.update(object);
                }
            });
        }
    });  
于 2021-09-22T10:24:55.100 回答