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

本文介绍了一个积分系统在文档下载过程中出现的问题,即用户下载文档后积分未正确更新。问题出现在事务处理和HTTP接口调用中,由于异常被捕获而未被抛出,导致事务未能回滚。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

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

<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />

    2、控制层DocHandlerController

@RequestMapping(value = "/download", method = RequestMethod.GET)
@Params(params = {@Param(name = "id")})
@Permitted
public Object downloadById(RequestContext context, Subject<UserInfo> 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<String, String> param = new HashMap<String, String>();
	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。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值