在做项目的时候遇到个问题,下面是我写的一部分方法,这个方法中引用的newDbsx()这个方法使用了 @Transacitonal 这个注解,但是在这个放法中没有生效
public YjptSjbh submit(String shld, Map<String, Object> result) throws Exception {
// 报核指标id
Integer bhzbid = ArteryParamUtil.getInteger("bhzbid");
// 报核参数id(涉及参数id)
Integer bhcsid = ArteryParamUtil.getInteger("bhcsid");
// 报核id
Integer bhid = bhcsid != null ? bhcsid : bhzbid;
// 判断报核指标是否存在
if (!hasZb(bhid)) {
result.put("status", "nozb");
return null;
}
/**
* 删除消息
*/
deleteMessage();
// 存数据报核对象
YjptSjbh sjbh = getSjbhContent(result);
// 存附件
ApprovalContext context = createContext(sjbh, shld);
// 提交
int submit = context.submit();
// 更新状态
yjptSjbhMapper.updateLcztAndSfyxByBh(sjbh.getBh(), submit, 2);
if (StringUtils.isEmpty(shld)) {
Integer gljc = ArteryParamUtil.getInteger("gljc");
// 如果原先有参数值则更新没有的话新增一条
Map<String, Object> dqcsz = getDqcsz(gljc, null);
if (null != dqcsz.get("csz")) {
updateBhcs(gljc, sjbh);
} else {
insertShbhtoGd(gljc, sjbh);
}
} else {
// 发消息
dbsxHelperService.newDbsx(getMkdm(), sjbh.getBh(), shld, getMessageTitle(sjbh), YjptConsts.DJSP_APPLY_SPZ);
}
return sjbh;
}
原因:要解决这个问题,首先我们需要了解spring缓存的原理。spring cache的实现原理跟spring的事物管理类似,都是基于AOP的动态代理实现的:即都在方法调用前后
去获取方法的名称、参数、返回值,然后根据方法名称、参数生成缓存的key(自定义的key例外),进行缓存。debug可以看到调用的实际上是groupUserBiz
的代理类,基于cglib动态代理实现。当调用代理的方法时,代理可以整体控制实际的方法的入参和返回值。比如缓存结果,直接跳过执行实际的方法等。
具体来说就是我这个方法引用了本地的方法,被引用的方法中的注解在引用方法中不生效
修改方法:
1.可以把removeGroupUserStatusCached方法单独抽取到另外一个类里面,通过代理类引入。
2.通过((GroupUserService)AopContext.currentProxy()).removeGroupUserStatusCached方法获取当前类的代理类;
3.通过ApplicationContext获取当前类的代理对象,GroupUserService groupUserService = springContextUtil.getBean(GroupUserService.class);