【发布时间】:2016-07-26 22:50:02
【问题描述】:
我的应用程序加载了应处理的实体列表。这发生在使用调度器的类中
@Component
class TaskScheduler {
@Autowired
private TaskRepository taskRepository;
@Autowired
private HandlingService handlingService;
@Scheduled(fixedRate = 15000)
@Transactional
public void triggerTransactionStatusChangeHandling() {
taskRepository.findByStatus(Status.OPEN).stream()
.forEach(handlingService::handle);
}
}
在我的HandlingService 中,使用REQUIRES_NEW 作为传播级别来隔离处理每个任务。
@Component
class HandlingService {
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void handle(Task task) {
try {
processTask(task); // here the actual processing would take place
task.setStatus(Status.PROCCESED);
} catch (RuntimeException e) {
task.setStatus(Status.ERROR);
}
}
}
代码之所以有效,是因为我在 TaskScheduler 类上启动了父事务。如果我删除 @Transactional 注释,实体将不再受管理,并且对任务实体的更新不会传播到数据库。我认为将计划方法设为事务性并不自然。
据我所知,我有两个选择:
1.保持现在的代码。
- 也许只有我,这是一个正确的方法。
- 此变体访问数据库的次数最少。
2。从Scheduler中移除@Transactional注解,传递任务的id并在HandlingService中重新加载任务实体。
@Component
class HandlingService {
@Autowired
private TaskRepository taskRepository;
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void handle(Long taskId) {
Task task = taskRepository.findOne(taskId);
try {
processTask(task); // here the actual processing would take place
task.setStatus(Status.PROCCESED);
} catch (RuntimeException e) {
task.setStatus(Status.ERROR);
}
}
}
- 对数据库的访问次数较多(一个额外的查询/元素)
- 可以使用
@Async执行
您能否就解决此类问题的正确方法提供您的意见,也许是我不知道的另一种方法?
【问题讨论】:
标签: java hibernate jpa spring-data spring-data-jpa