Spring数据JPA:未提交每条记录的事务

时间:2017-02-01 06:13:30

标签: jpa transactions spring-data-jpa

我需要在循环中提交记录,并执行以下操作:

  • 删除状态为
  • 的记录(父级+子级)
  • 创建新记录,插入父+子 下面在循环中调用deleteOldAndsaveNew()方法,我希望每次提交内部操作。

PFB代码段:

通话方式: //服务层

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;
    }

// Dao图层

   @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)并尝试仅在每次需要提交的操作上使用Transactional。

请建议。

感谢。

1 个答案:

答案 0 :(得分:0)

谢谢,我能够解决这个问题。通过在单独的类中使用以下代码并从类级别删除Transactional。

通话方式:

public int updateObsoleteDocumentsFromList(List<DocumentChildDTO> childDocuments) {
         LOG.info("Start updating Obsolete documents (nb docs to update: " + childDocuments.size()+ ")" );

         int nbDocsUpdated = 0;
        try {
            DocumentStatus statusObsolete = docStatusService.findByName(StatusType.Old.toString());
            Status statusValidated = docStatusService.findByName(StatusType.Validated.toString());
            for (DocumentChildDTO docChildDTO : childDocuments) {
                if (docChildDTO .getDocument() != null) {
                    DocumentDTO documentDTO = docChildDTO .getDocument();
                    Document document = documentMapper.documentDTOToDocument(documentDTO);
                    nbDocsUpdated = documentDAO.deleteObsoleteAndSaveValidatedDoc(docChildDTO, document, statusValidated,  
                            nbDocsUpdated, statusObsolete);
                }
            }
        }

        return nbDocsUpdated;
    }

被调用的方法(在单独的类中)

@Transactional
    public Integer deleteObsoleteAndSaveValidatedDoc(DocumentChildDTO docChildDTO, Document document,
            DocumentStatus statusValidated, int nbDocsUpdated ,DocumentStatus statusObsolete) {

        Document latestDoc = getLatestChildDocument(document);
        boolean isDBDocObsolete = isDBDocObsolete(statusObsolete, latestDoc);
        boolean createDoc = false;
        DocumentDTO documentDTO;
        if ((latestDoc == null) || isDBDocObsolete) {
            createDoc = true;
        }

        if (isDBDocObsolete) {
            documentChildDao.deleteChildDocumentByDocId(latestDoc.getId());
            deleteDocumentById(latestDoc.getId());
        }
        if (createDoc) {
            document.setUpdateDate(new Date());
            document.setStatus(statusValidated);
            document.setIsObsolete(false);

            documentDTO = saveDocument(document);
            if (documentDTO == null) {
                LOG.error("Cannot create document " + document.getName());
            } else {
                nbDocsUpdated++;
            }
            docChildDTO.setDocument(documentDTO);
            if (documentChildDao.save(docChildDTO) == null) {
                LOG.error("Cannot create child document " + docChildDTO.getNameChild());
            }

        return nbDocsUpdated;
    }

感谢。