gpt4 book ai didi

java - 如何为每个计划方法分配一个 Hibernate session

转载 作者:行者123 更新时间:2023-11-30 05:50:31 26 4
gpt4 key购买 nike

我有以下设置:

@Component
public class Scheduler {
Logger logger = LoggerFactory.getLogger(this.getClass());

@Autowired
BatchService batchService;

@Scheduled(cron = "0 */1 * ? * *")
void tick() {
logger.info("Beginning of a batch tick");
batchService.refundNotAssignedVisits();
logger.info("End of the batch tick");
}
}

BatchService 包含以下内容:

@Service
public class BatchServiceImpl implements BatchService {

Logger logger = LoggerFactory.getLogger(this.getClass());

@Autowired
VisitService visitService;

@Override
@Transactional
public void refundNotAssignedVisits() {
logger.info("Start automatic refund of past visits being assigned");

Set<Visit> visits = visitService.findRefundableVisits();

if(visits != null && visits.size() != 0) {
logger.info("Found " + visits.size() + " visits to refund with IDs: " + visits.stream().map(x -> x.getId().toString()).collect(Collectors.joining(", ")));
visits.forEach(x -> {
logger.info("Refunding visit with ID: " + x.getId());
try {
visitService.cancel(x);
logger.info("Visit successfully refunded!");
}
catch(Exception e) {
logger.error("Error while refunding visit...", e);
}
});
}
else {
logger.info("Found no visit to refund.");
}

logger.info("End of automatic refund");
}
}

cancel 方法定义如下:

@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public Visit cancel(Visit visit) throws Exception {
// Some business logic
}

出于商业目的,我需要 cancel 方法每次调用处理一笔事务,目前,refundNotAssignedVisits@Transactional为了启用 Hibernate session ,以便我能够在 cancel 方法中对相关实体使用延迟加载。

这会导致重复提交等问题,我想知道什么是实现我想要的效果的好模式:有一个 @Scheduled 方法来启用 Hibernate session ,以便多次调用另一个 session 每次调用一次事务的方法。

最佳答案

@TransactionalREQUIRES_NEW 将创建另一个新的 Hibernate session ,因此 cancel() 内的 session 将与用于加载对我来说似乎很尴尬的实体。通常,我们使用相同的 session 来加载和管理事务中的相同实体。

我将代码重构为以下内容:

VisitService:

//Cannel by visitorId and load the Visitor by Id in a new transaction
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public Visit cancel(Integer visitorId) throws Exception {
Visit visit= session.get(Visit.class , visitorId);
cancel(visit);
}

@Override
public Visit cancel(Visit visit) throws Exception {
// Some business logic
}

//Add method to return the IDs only
@Transactional(readOnly=true)
public Set<Integer> findRefundableVisitId(){

}

批量服务:

//@Transactional  (Do not require anymore)
public void refundNotAssignedVisits() {
logger.info("Start automatic refund of past visits being assigned");

Set<Integer> refundVisitIds = visitService.findRefundableVisitId();
refundVisitIds.forEach( id-> {
try {
visitService.refund(id);
logger.info("Visit successfully refunded!");
}
catch(Exception e) {
logger.error("Error while refunding visit...", e);
}
});
}

通过这种方式,每个退款都在自己的事务中执行,并且用于加载退款访问者的事务不需要等待所有退款完成才能提交,并且不再有“重复提交”。

关于java - 如何为每个计划方法分配一个 Hibernate session ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53986684/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com