我已经开发了用于在异步任务中将文件集成到数据库中的API。我希望处理整个文件,并在数据库中记录每个错误。
我的API调用此服务
@Service
public class ImportFichier {
@Async("taskExecutor")
public void importReference(ImportFichierDTO importFichierDTO,
List<Reference> references,
Long idEntite,
Long currentUserId,
boolean update){
log.debug("Request to importReference pour entite : {}", idEntite);
for(Reference reference : references) {
if (update) {
referentielService.update(idEntite, reference, currentUserId, importFichierDTO.getId());
} else {
referentielService.add(idEntite, reference, currentUserId, importFichierDTO.getId());
}
}
// mise à jour de l'heure de fin du traitement d'import
importFichierDTO.setDateFin(ZonedDateTime.now());
importFichierService.save(importFichierDTO);
return;
}
要添加数据,请致电此服务:
@Service
@Transactional
public class ReferentielCompteurServiceImpl implements ReferentielCompteurService {
....
@Override
@Transactional(noRollbackFor = {CustomException.class, ConstraintViolationException.class})
public Compteur add(Compteur compteur, Long entiteMereId, Long entiteId, Long userId, Long importId) {
Optional<ArticleEtat> articleEtat = articleEtatRepository.findOneByCode(compteur.getCodeEtat());
if (!articleEtat.isPresent()) {
if (importId > 0) {
importFichierTraceService.add(importId, compteur.getUuidReference().toString(), CustomError.ERROR_ARTICLE_ETAT_NOT_FOUND.getErrorDescription());
return compteur;
} else {
throw new CustomException(CustomError.ERROR_ARTICLE_ETAT_NOT_FOUND);
}
}
....
ReferentielCompteurDTO result = save(referentielCompteurDTO, importId);
并且方法“保存”在同一服务中:
@Override
@Transactional(noRollbackFor = {CustomException.class, ConstraintViolationException.class})
public ReferentielCompteurDTO save(ReferentielCompteurDTO referentielCompteurDTO, Long importId) {
log.debug("Request to save ReferentielCompteur : {}", referentielCompteurDTO);
if (referentielCompteurDTO.getDateCreation() == null) {
referentielCompteurDTO.setDateCreation(ZonedDateTime.now());
}
referentielCompteurDTO.setDateModification(ZonedDateTime.now());
ReferentielCompteur referentielCompteur = referentielCompteurMapper.toEntity(referentielCompteurDTO);
try {
referentielCompteur = referentielCompteurRepository.save(referentielCompteur);
} catch (ConstraintViolationException cve) {
importFichierTraceService.add(importId, referentielCompteurDTO.getReferenceId().toString(), cve.getMessage());
}
return referentielCompteurMapper.toDto(referentielCompteur);
}
[当我生成ConstraintViolationException时,我有此异常:
Transaction was marked for rollback only; cannot commit' and exception = 'Transaction was marked for rollback only; cannot commit; nested exception is org.hibernate.TransactionException: Transaction was marked for rollback only; cannot commit'
org.springframework.orm.jpa.JpaSystemException: Transaction was marked for rollback only; cannot commit; nested exception is org.hibernate.TransactionException: Transaction was marked for rollback only; cannot commit
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:312)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:223)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:540)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:746)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:714)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:532)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:304)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
我看过几篇文章,但是我不明白如何解决这个问题,并且有可能
您能帮我吗?
按照Deinum先生的建议,我尝试:
for importFichierTraceService.add
@Transactional(propagation = REQUIRES_NEW)
public void add(Long importId, String line, String message) {
我删除@Transactional并捕获异常
@Override
public ReferentielCompteurDTO save(ReferentielCompteurDTO referentielCompteurDTO, Long importId) {
并在以下位置添加catch异常:
@Override
public Compteur add(Compteur compteur, Long entiteMereId, Long entiteId, Long userId, Long importId) {
try {
result = save(referentielCompteurDTO, importId);
} catch (ConstraintViolationException cve) {
importFichierTraceService.add(importId, referentielCompteurDTO.getReferenceId().toString(), cve.getMessage());
return compteur;
}
结果相同