在项目中遇到了这样的问题,用户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。