在Spring应用程序中管理事务

时间:2019-01-18 11:28:21

标签: spring spring-boot spring-mvc transactional transactional-database

我正在使用springboot来开发我的应用程序,在服务中我正在使用一个名为SubmitPostDetails()的名称来调用方法->此方法将请求连同一些参数一起发送给方法-X()并插入将详细信息发布到系统中。

完成后,dao中的同一方法将调用另一个方法Y()来更新另一个表中的某些记录。现在,我担心的是如果第一个方法执行而第二个方法抛出异常。如果发生任何异常,我想回退由第一种方法完成的插入。使用@Transactional尝试过,但是没有用

[这是一种名为“提交帖子详细信息”的服务方法] [1]

public String submitPost( SubmitPostDetailsDto submitPostDetailsDto) throws IOException {
    // TODO Auto-generated method stub
    LOGGER.debug("Request received from controller to submit the post details and upload the scanned document");
    LOGGER.debug("Sending request to get the unique application ID");
    String uniqueApplicationId = applicationUtilityClass.getUniqueApplicationId(submitPostDetailsDto);
    LOGGER.debug("Checking if the applicaiton id is null");
    if(uniqueApplicationId==null||uniqueApplicationId.isEmpty())
    {
        LOGGER.error("The unique application id is null or empty");
        LOGGER.error("Returning message -  Application Id could not be generated, Please contact the administrator");
        return readApplicationConstants.getApplicationIdGenerationErrorMessage(); //Returns error message - Id could not be generated, Please contact the administrator

    }
    LOGGER.debug("Unique application id generated is: "+uniqueApplicationId);
    LOGGER.debug("Sending Request to determine the document type and return the uploadPath");
    String uploadPath = applicationUtilityClass.uploadFile(submitPostDetailsDto.getDocumentType(),submitPostDetailsDto.getFile(),uniqueApplicationId );

    if(uploadPath==null)
    {
        LOGGER.error("An error occured in uploadFile method in ApplicationUtilityClass");
        LOGGER.error("ERROR! The file cannot be uploaded");
        LOGGER.error("Returning ERROR message to controller");
        return readApplicationConstants.getApplicationIdGenerationErrorMessage();
    }
    else
    {
        LOGGER.debug("Path of uploaded file returned is: "+uploadPath);
        LOGGER.debug("Sending request to Dao to submit postDetailsDto along with applicationId and uploadPath into the database");

        return registerApplicationDao.submitPostDetails(submitPostDetailsDto,uniqueApplicationId,uploadPath);
    }
}

这是Dao方法提交帖子的详细信息-     @交易     公共字符串submitPostDetails(SubmitPostDetailsDto SubmitPostDetailsDto,字符串uniqueApplicationId,字符串uploadPath)     {

    // TODO Auto-generated method stub

    LOGGER.debug("Request received from registerApplicationService - submitPost method to submit document details, uniqueApplicationId,uploadPath into database");
    LOGGER.debug("Creating hashmap of objects");
    SqlParameterSource postDetailsParams = new MapSqlParameterSource();
    LOGGER.debug("Hashmap created successfully");
    LOGGER.debug("Putting values in the hashmap");
    ((MapSqlParameterSource) postDetailsParams).addValue("applicationId", uniqueApplicationId);
    ((MapSqlParameterSource) postDetailsParams).addValue("senderName", submitPostDetailsDto.getSenderName());
    ((MapSqlParameterSource) postDetailsParams).addValue("senderPoc", submitPostDetailsDto.getPointOfContact());
    ((MapSqlParameterSource) postDetailsParams).addValue("senderContact",submitPostDetailsDto.getContactNumber());
    ((MapSqlParameterSource) postDetailsParams).addValue("dateReceived", submitPostDetailsDto.getDateReceived());
    ((MapSqlParameterSource) postDetailsParams).addValue("priority", submitPostDetailsDto.getPriority());
    ((MapSqlParameterSource) postDetailsParams).addValue("subject", submitPostDetailsDto.getSubject());
    ((MapSqlParameterSource) postDetailsParams).addValue("documentType", submitPostDetailsDto.getDocumentType());
    ((MapSqlParameterSource) postDetailsParams).addValue("documentPath", uploadPath);
    ((MapSqlParameterSource) postDetailsParams).addValue("documentRemarks", submitPostDetailsDto.getAdditionalComments());
    LOGGER.debug("Values succcessfully inserted into hashmap");
    LOGGER.debug("Creating object of KeyHolder to return the auto generated key after insertion of the post details");
    KeyHolder holder = new GeneratedKeyHolder();
    try {
        LOGGER.debug("Executing the query to submit post details");
        getJdbcTemplate().update(registerApplicationConfig.getSubmitPostDetails(),postDetailsParams, holder);
        LOGGER.debug("The key which is generated is: "+holder.getKey().intValue());
        Integer docId = holder.getKey().intValue();//To get the primary key (Generated by Auto-Increment) of the document details table
        LOGGER.debug("Details inserted successfully, Key of inserted application id is: "+holder.getKey().intValue());
        LOGGER.debug("Calling method get the Id of the owner to whom the document is assigned");
        Integer documentOwnerId = getDocumentOwnerId(submitPostDetailsDto.getOwnerName());//Auto-incremented id of the DH in the users table
        LOGGER.debug("The document owner id corresponding to ownerName: "+submitPostDetailsDto.getOwnerName()+" and applicationId: "+uniqueApplicationId+" is: "+documentOwnerId);
        LOGGER.debug("Calling method to fill the document status table");
        LOGGER.debug("Sending control to fillDocumentStatusTable");




        Integer submitStatus = fillDocumentStatusTable(docId,documentOwnerId);

        if(submitStatus == -1)
        {
            LOGGER.error("Details cannot be inserted in document status table");
            LOGGER.error("Returning ERROR Message");
            return readApplicationConstants.getPostDetailsSubmissionFailure();//Returns - Post cannot be submitted

        }
        LOGGER.debug("The document has been submitted successfully ");
        LOGGER.debug("Calling method to return application id on the basis of id(PK) :" +docId);
        String uniqueId = getApplicationIdById(docId);



        LOGGER.debug("The unique id corresponding to the generated primary key is: "+docId);
        return uniqueId;
    }
    catch(RuntimeException e)
    {
        LOGGER.error("The exception is: "+e);
        LOGGER.error("Returning NULL");
        return null;
    }


}

此方法调用一个方法-fillDocumentStatusTable

private Integer fillDocumentStatusTable(Integer docId, Integer documentOwnerId) {
    // TODO Auto-generated method stub
    LOGGER.debug("In fillDocumentStatusTable to submit the details in the documentStatus table");
    LOGGER.debug("Creating hashmap of objects");
    Map<String,Object>docStatusParams = new HashMap<>();
    LOGGER.debug("Hashmap successfully created");
    LOGGER.debug("Putting values in the hashmap");
    docStatusParams.put("ownerId", documentOwnerId);
    docStatusParams.put("status",readApplicationConstants.getDocumentNotStartedStatus());
    docStatusParams.put("documentId", docId);
    try
    {
        LOGGER.debug("In try block of fillDocumentStatusTable to submit details in the doc status table");
        LOGGER.debug("Executing query to submit the details in document status table");
        return getJdbcTemplate().update(registerApplicationConfig.getSubmitDocumentStatus(), docStatusParams);

    }
    catch(Exception e)
    {
        LOGGER.error("An error occured while submitting the details in doc status table: "+e);
        LOGGER.error("returning -1");
        return -1;

    }
}

1 个答案:

答案 0 :(得分:1)

每个调用的方法都应该在同一个事务中->应该带有@Transactional注释。

如果您决定捕获异常并想要回滚,则应将其重新抛出,例如:

try {
    doSomething();
catch (Exception e) {
    logger.error("exception occurred", e);
    throw new MyException(e);
}

然后您可以在注释中使用

@Transactional(rollbackFor=MyExceptoin.class)

应该可以解决问题。