【发布时间】:2017-06-17 19:16:49
【问题描述】:
我需要通过以下操作在循环中提交记录:
- 删除旧状态的记录(父+子)
- 创建新记录,插入父+子 下面的 deleteOldAndsaveNew() 方法在循环中调用,我希望每次都提交里面的操作。
PFB代码sn-p:
调用方法: //服务层
public int updateOldDocumentsFromList(List<DocumentChildDTO> childDocuments) {
int nbDocsUpdated = 0;
for (DocumentChildDTO docChildDTO : childDocuments) {
if (docChildDTO .getDocument() != null) {
DocumentDTO documentDTO = docChildDTO .getDocument();
Document document = documentMapper.documentDTOToDocument(documentDTO);
Document latestDoc = getLatestChildDocument(document);
DocumentStatus statusObsolete = docStatusService.findByName(DocumentStatusType.Obsolete.toString());
DocumentStatus statusValidated = docStatusService.findByName(DocumentStatusType.Validated.toString());
boolean isDBDocObsolete = isDBDocObsolete(statusObsolete, latestDoc);
boolean createDoc = false;
nbDocsUpdated = documentDAO.deleteObsoleteAndSaveValidatedDoc(docChildDTO, document, latestDoc, statusValidated, isDBDocObsolete,
nbDocsUpdated, createDoc);
}
}
LOG.info("End updating olddocouments (nb docs updated: " + nbDocsUpdated + ")");
return nbDocsUpdated;
}
//道层
@Transactional(propagation = Propagation.REQUIRES_NEW)
public int deleteObsoleteAndSaveValidatedDoc(DocumentChildDTO docChildDTO, Document document, Document latestDoc,
DocumentStatus statusValidated, boolean isDBDocObsolete, int nbDocsUpdated, boolean createDoc) {
DocumentStatus statusObsolete = getOldDocStatus();
if ((latestDoc == null) || isDBDocObsolete(statusObsolete, latestDoc)) {
createDoc = true;
}
if (isDBDocObsolete(statusObsolete, latestDoc)) {
documentDAO.delete(latestDoc);
}
DocumentDTO documentDTO;
if (createDoc) {
setters for new document
// Save the new doc
documentDTO = docService.save(document);
if (documentDTO == null) {
LOG.error("Error");
} else {
nbDocsUpdated++;
}
docChildDTO.setDocument(documentDTO);
if (save(docChildDTO) == null) {
LOG.error("Error");
}
}
return nbDocsUpdated;
}
Delete document method
@PersistenceContext
private EntityManager entityManager;
public void delete(Document obsoleteDocument) {
this.entityManager.remove(obsoleteDocument);
this.entityManager.flush();
}
@Transactional
public void saveDocument(Document document) {
LOG.debug("Request to save Document : {}", document);
this.entityManager.persist(document);
this.entityManager.flush();
}
@Transactional
public void save(DocumentChild documentChild ) {
LOG.debug("Request to save documentChild : {}", documentChild );
documentChildDao.saveAndFlush(documentChild);
}
我已经使用实体管理器和 Spring 数据方法来查看哪一个有效,我可以看到生成了删除语句和 2 个插入语句(父和子),并且 id 也增加了,但它没有在 db 中反映/提交.
这行@Transactional(propagation = Propagation.REQUIRES_NEW) 是否不能保证每次访问deleteOldAndsaveNew() 方法时都提交其中的操作?
编辑:我已删除 (propagation = Propagation.REQUIRES_NEW) 并尝试仅在每次都需要提交的操作上使用事务。
请提出建议。
谢谢。
【问题讨论】:
-
这里有人,如果我不够清楚,请告诉我?谢谢
-
尝试从 DAO 方法中删除 @Transactional.. 只需在服务层使用它.. 其中定义了 deleteOldAndsaveNew 方法
-
感谢 Maciej...从 DAO 方法中删除事务没有帮助。请问还有什么建议吗?
-
我尝试在服务类级别上删除 @Transactional 并将其仅放在 deleteOldAndsaveNew 上,但没有成功..
-
另外,在每次操作后调用 flush 并不是一个好主意。删除那些 .. em 将在事务结束时刷新..
标签: jpa transactions spring-data-jpa