从另一个线程调用@Transactional方法(Runnable)

有没有简单的解决方案在新线程中使用JPA将数据保存到数据库中?

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

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

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

编辑2:我的问题代码的简化版本来到这里。 从调度程序调用saveTaskResult()时,将打印出消息,但不会将任何内容保存到db中。 但每当我从控制器调用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工厂获得事务性Spring bean的实例,或者通过dependency injection,你得到的实际上是围绕bean的代理。 此代理在调用实际方法之前启动事务,并在方法完成后提交或回滚事务。

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

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