Ond*_*hal 16 java spring 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);
}
}
Run Code Online (Sandbox Code Playgroud)
JB *_*zet 24
代码的问题在于您希望在调用时启动事务saveTaskResult()
.这不会发生,因为Spring使用AOP来启动和停止事务.
如果从bean工厂获得事务性Spring bean的实例,或者通过依赖注入,你得到的实际上是围绕bean的代理.此代理在调用实际方法之前启动事务,并在方法完成后提交或回滚事务.
在这种情况下,您可以调用bean的本地方法,而无需通过事务代理.将saveTaskResult()
方法(带注释@Transactional
)放在另一个Spring bean中.将其他Spring bean注入DemoService,并从DemoService调用另一个Spring bean,一切都会好的.
事务保存在线程本地存储中。
如果您的其他方法正在运行带注释的线程@Transactional
。
默认设置为REQUIRED
,这意味着如果您从不同的线程运行注释的方法@Transacitonal
,您将拥有一个新事务(因为该线程的线程本地存储中没有保存任何事务)。
另一种选择(除了创建带有 @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);
}
});
}
});
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
11396 次 |
最近记录: |