在开发中,遇到了一个这样的问题,用户登录,写日志等需要给用户加系统积分,但为了减轻系统压力,而且为了避免因为加积分失败,而影响写日志等操作失败(事务设在Service方法级别,而保存日志与加积分操作在同一个service中)
我将加积分用JMS实现,是一种异步操作,每次用户登录时,向JMS发送一个积分对象,然后JMS消费队列会去取这个积分对象,然后执行加积分操作,执行加积分的同时,会向内存中写一段特制的代码,在用户请求返回之前,会去内存中查一次是否有加积分代码存在,如果在则写入到Response中,由前台JS进行监控,然后执行加积分操作,并及时提示用户。
到这里问题就来了,加积分是异步的,但又需要向用户及时显示加积分的结果,目前我们的解决方案是在用户请求返回之前,我们统一的将线程休眠100ms,等待加积分执行完,保存能从内存中取到加积分的特制代码,并写入response,并在前台及时告知用户,加积分成功。但是由于系统与网络执行速度不确定,所以休眠100ms,导致的结果是有时候用户能看到提示框,告诉它加积分了,但有时候虽然加积分了,但没有提示框弹出。
不知道各位有没有好的解决方案,当然将积分同步这样的我们也考虑过。
比如按如下执行
public class DiaryServiceImpl implements{
private DiaryDao diaryDao;
private ScoreDao scoreDao;
public void saveDiary(Diary diary){
diaryDao.save(diary);
//SocreData scoreData
tru{
scoreDao.save(scoreData);
}catch(Exception e){
//捕获异常,辟免因为加积分失败,导致写日志失败
}
}
}
但经过讨论,我们觉得有大在用户量访问的时候,同步加积分可能对系统造成过大的压力,所以我们用JMS 异步方式加积分,但遇到了我在开始述说的问题,不知各位有没有好的解决方案,好像我没有积分了,所以也不能提供悬赏,看在大家都热衷于JAVA,大家都来帮忙讨论一下吧,谢谢了。
您说的好像很麻烦。
我不太明白
为什么不是ajax异步处理?
线程休眠100ms的方法绝对不可取,这个是自杀式写法。
如果你的加积分动作是个阻塞动作,比如数据库操作,而必须要做到异步操作,那我建议你只对阻塞部分做异步操作。
我的理解是你分了两步
1:用户发帖->写入数据库->返回用户新页面
2:计算积分->积分写入数据库->内存中更新
何不这样:
1:用户发帖->写入数据库->计算积分->更新内存中的积分->返回新页面
2:积分写入数据库
让持久层滞后,但内存中实时更新。毕竟,我感觉你的积分不是那么重要。
如果在我的项目中,就不是积分了,而是钱,那就必须要放到一个事务中去了,即使那样,也慢不了多少,至少比你的100ms要快好多。