关于spring事物控制加入try-catch后果的体会

    在项目中遇到了这样的问题,用户1上传知识文档,用户2、用户3等下载或者浏览对应知识文档,用户1增加相应积分,用户2、用户3扣除相应积分。

    目前问题是,文档正常下载,但是没有增加对应的积分,具体原因参见代码:

    1、事物控制通过注解,spring-context.xml文件

    2、控制层DocHandlerController

@RequestMapping(value = "/download", method = RequestMethod.GET)
@Params(params = {@Param(name = "id")})
@Permitted
public Object downloadById(RequestContext context, Subject subject) throws IOException {
    String id = (String) context.getParam("id");
    return docDownloadService.downloadById(id, subject.getCurrentUserId(), context.getRequest());
}

    3、docDownServiceImpl,通过@Transactional进行注解控制,但要注意的是,try-catch部分没有继续抛出异常,事物控制在这一块无效。

@Transactional
    public Object downloadById(String id, String userId, HttpServletRequest request) {
        DocInfo docInfo = docInfoDao.get(new CompanyPK(id, CompanyIdThreadLocalUtil.get()));
        //改变总下载数
        docInfo.setDownloadNum(docInfo.getDownloadNum() + 1);
        //改变被别人下载数
        if (!userId.equals(docInfo.getCreateUserId())) {
            if (null != docInfo.getOthersDownloadNum()) {
                docInfo.setOthersDownloadNum(docInfo.getOthersDownloadNum() + 1);
            } else {
                docInfo.setOthersDownloadNum(1);
            }
        }

        docInfo = docInfoDao.update(docInfo);
        Integer othersDownloadNum = docInfo.getOthersDownloadNum();

        //当前用户不是发布用户,
        if (!userId.equals(docInfo.getCreateUserId())) {
            //判断当前用户是否下载过
            Boolean downloadRecord = (Boolean) WebServiceUtil.invokeLdsConnection(SystemConfigUtil.getAdminSystemUrl(request), "IntegralOutService", "validUserIsDownLoad", new Object[]{userId,
                    "isDownLoad", docInfo.getId(), CompanyIdThreadLocalUtil.get(), AskConstant.SYS_RULE_INTEGRAL_KNOWLEDGE
            });
            if (downloadRecord.booleanValue()) {

                if (DocConstant.SOURCES_FRONT.equals(docInfo.getSources())) {//学员端的知识才走积分接口
                    //未曾下载过
                    //知识被下载大于等于{}人次得{}分
                    IntegralRuleUtil.addIntegral(docInfo.getCreateUserId(), "knowledge_download", SysIntegralConstant.SYS_RULE_INTEGRAL_KNOWLEDGE, docInfo.getId(), CompanyIdThreadLocalUtil.get(), othersDownloadNum);
                }
                //文档下载积分大于0,才扣除积分
                if (docInfo.getIntegral() != null && docInfo.getIntegral() > 0) {
                    //积分接口调用(下载后扣除当前用户的积分)
                    IntegralRuleUtil.subtractIntegralByScore(userId, "isDownLoad", SysIntegralConstant.SYS_RULE_INTEGRAL_KNOWLEDGE, id, CompanyIdThreadLocalUtil.get(), docInfo.getIntegral());
                }
                if (DocConstant.SOURCES_FRONT.equals(docInfo.getSources())) {//学员端的知识才走积分接口
                    //上传文档者增加积分(设置的下载积分数)
                	IntegralRuleUtil.addIntegralByScore(docInfo.getCreateUserId(), "isDownLoad_add", SysIntegralConstant.SYS_RULE_INTEGRAL_KNOWLEDGE, docInfo.getId(), docInfo.getCompanyId(), docInfo.getIntegral());
                }
            }

        }
        try {
            return UploadUtil.downloadDoc(docInfo.getOriginalFile(), docInfo.getUploadName(), request);
        } catch (Exception e) {
            throw new ValidationException("文件不存在");
        }
    }

4、IntegralRuleUtil通过http调用积分接口

public static ResultMsg addIntegral(String userId,String ruleType,String businessCode,String businessId,String companyId,Integer number){
    String messageUrl = (String)SystemConfigUtil.getContextProperty("zxy.message.service.path");
    IntegralConfig integralConfig = new IntegralConfig(userId, ruleType, businessCode, businessId, companyId, messageUrl,number);
    return IntegralUtils.addIntegral(integralConfig);
}
public static ResultMsg addIntegral(IntegralConfig integralConfig) {
    try {
	Map param = new HashMap();
	param.put("integralConfig", JsonUtils.toJsonString(integralConfig));
	String jsonResult = HttpClientUtils.post(integralConfig.getUrl()+"/api/integral/add", param);
	return JsonUtils.jsonString2Bean(jsonResult, ResultMsg.class);
    } catch (Exception e) {
	logger.error("加积分接口调用异常,用户:" + integralConfig.getUserId() + ";积分类型:" + integralConfig.getRuleType(), e);
	return ResultMsg.getFailMsg("加积分接口调用失败,异常信息:"+e);
    }
}

    这里的http请求放到了try-catch中,由于项目部署时,端口配置错误,http调用接口失败,但是这里的异常被捕获了,使得事物失效,造成的结果是文档被下载n次,但是积分都没有。

    总结:如果是在事物中,最好不要使用try-catch。



你可能感兴趣的:(关于spring事物控制加入try-catch后果的体会)