请教:如何解决并发请求
问题背景:我提供一个安卓服务端的api接口,记录流水的,有个唯一字段标示(非主键),先查询,判断如果有则更新,没有则插入。但是部署上线后总是有人使用工具恶意的并发请求,同一秒种请求30次。导致我的方法总是多插入数据。
首先我使用了synchronized关键字同步这个方法,然后查询这条流水的时候添加了 for update(包在了事务里面,并且是innoDb) ,但是还是不能控制住。以下为伪代码:
public void saveOrUpdateLog(String id){ synchronized (this){ tx.begin();//事务开启 String sql = "select id from log where id = ? for update"; Log log = Db.select(sql,id); if(log == null){ //保存 }else{ //修改 } tx.conmit(); } }
哪位大牛给我讲一讲啊?支个招!感激不尽!
回来补充解决方案:
在类里面定义了一个 private static String lock = new String();
然后使用synchronized(lock){
}
这样话话经过并发测试以后,发现此处代码正常了,一个线程进入,出去以后,下一个线程进入。嘿嘿,搞定啦,当然,效率有点降低,但是数据不会错乱啦!!!!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(19)
你说的太不清楚了.......是不想要多于的数据?还是要控制并发产生的错误id?
我想控制 不生成多条记录
saveOrUpdateLog方法所在的对象在你的应用中有很多个吗?如果有很多个,请这个类中加入一个静态变量,用这个静态变量做为锁。
嗯好 我试一下
api没有身份验证等的措施么,或者读日志,统计下那个ip或者客户端有恶意请求,限制下或者封了
还没有做到那步,想从代码上控制一下,这样对自己也是个提高
不懂java,不过你的示例代码是可以做到防止插入多条的。
假如代码很多的话,可以试着简化到最小可以重现的代码,然后再分析。
写个过滤器,对接口的访问速度做一个限制。 比如,访问一次,2秒内再访问就返回失败。
建一个唯一索引就可以了。
假定你这个 saveOrUpdateLog(String id) 写在名为 TransLog 类里面,再假定每次调用 saveOrupdateLog(...) 这个方法时是不同的对象,那么此方法中的 synchronized 关键字是毫无作用的,在多个线程对同一个对象实例操作时才有用。
回复
贴出更多更详细的代码来,才能解决问题
我没写在model里,我写在了service里面,我这么写是不是有问题,我感觉我没招了已经
你要提供你的恶意访问的特征才行呀。能抓到特征点就能做过滤
能提供个思路吗?
过滤恶意访问。
能大概说下后面那句的大致思路吗?
在保存之前再做一次检测,如果还是不行或者效果不好,就做一个请求或者数据表操作的限制
能提供个思路吗
恶意的过滤掉,才是解决的办法吧