问个问题:这种情况下,当请求速度快到一定程度后,可否突破验证?

finemi 2015-11-01 01:33:34
加精
打个比方,一个web程序中领取代金券的例子
首先数据库中:有一个字段代表是否领取过代金券
程序中:先读取数据库,判断该字段值,true则领取过,不允许再次领取,false则进行下一步领取,并再次发送sql设置标识字段为true

那么当连续2个请求快到一定程度(假设),也就是在领取方法中读取数据库判断还未完成之前第二个请求又进入该方法了,会否突破验证?
我觉得应该是不能的吧,始终应该会有一个先后的?
...全文
1475 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
Intboy 2015-11-13
  • 打赏
  • 举报
回复
并发加锁,如果Oracle的话可以对sql 加for update锁住。
sanbagu 2015-11-13
  • 打赏
  • 举报
回复
数据库一般有对于事务的锁表或者行级锁,但是还是手动上锁可靠些。
独自漫步 2015-11-13
  • 打赏
  • 举报
回复
引用 8 楼 shijing266 的回复:
[quote=引用 7 楼 u011643186 的回复:] 这哥只要在jsp页面做一个防止重复提交就可以了。 或者后台加一个随机数来标识请求只能一次。
恩,这样也是一种处理方法[/quote] 两个页面同时用一个账号呢?
树成 2015-11-08
  • 打赏
  • 举报
回复
一般来说,处理这种并发问题都用数据库锁,如何用 就是在判断查询语句后加上for update或者类似的加锁功能,我以oracle数据库为例 例如 select * from user where id=1001 for update . 这样就把用户为1001这行数据锁住,后面任何请求过来都会等待,直到第一个执行这个查询的人讲事物锁释放,后面的请求才能继续操作,这样就不会有脏读的问题了。 这里存在一个性能问题,就是如果前面的请求不释放锁后面的请求就会等待,如果业务逻辑复杂而且耗时较长,或者这个操作的并发量极大,会非常影响用户体验,处理这种问题有多种方式,但是每种方式都有优劣,要根据你自身业务的需求来定制。一种是使用nowait方式,即是遇到被锁则终止操作要求用户重新提交。另一种是我们如今常用的方式——乐观锁,即是我们一开始并不去判断冲突的问题,而是先进行业务逻辑的操作(先认为它的操作是合理合法的),然后在最终要提交时做判断并加锁,如果判断正确则pass,如果错误则回滚之前的操作。
Royal_lr 2015-11-07
  • 打赏
  • 举报
回复
楼主所说的问题,属于线程的安全性了,这种并发情况肯定会涉及到事务了,事务的隔离级别能够解释这个问题,,在并发时,,事务一般产生脏读,重复读,幻读,,三种情况。 脏读就是当一个事务在修改数据时,,,另一个事务却读取了它。 重复读也是在2个事务间,第一个事务在2次读取数据之间,由于第二个事务的修改,第一个事务2次读取的数据可能是不一样的。 幻读就是也是在2次读取数据之间,由于第二个事务插入了一条数据,第一个事务第2次读取的数据会多一条。 大多数数据库默认的隔离级别为READ COMMITTED,这个只能防止脏读
finemi 2015-11-07
  • 打赏
  • 举报
回复
我自己测试了下,使用HttpClient连续发送的两个请求,无法突破,可能速度还是不够快。 也就是说,一般只要不是安全性要求特别高的,都没有必要同步。 而安全性特别高的,我的想法是,对于我上面举的一个例子,使用一个Session范围的对象(即每个用户只能领取一次)为同步锁的持有对象,这样应该是可以的吧,既不映像效率也达到安全性了?
纯粹码农 2015-11-07
  • 打赏
  • 举报
回复
如果加锁并且先改变数据库中的值得话可以避免重复领取,但是网站速度会跟不上aaaaaaaaaaaaaaaaaaaaaa
刹那芳华2 2015-11-05
  • 打赏
  • 举报
回复
strut2中有防止重复提交的知识,楼主可以去看下,这有关同步和异步方面的知识!
业余草 2015-11-05
  • 打赏
  • 举报
回复
突破验证是肯定的,但是也不能给数据库加锁! 数据量大的话,你的网站就死了
cscxxx 2015-11-04
  • 打赏
  • 举报
回复
可以是点了领取时先用Javascript把领取隐藏再ajax到后台,等后台跑完了再回到前台,这样应该就没这问题。
  • 打赏
  • 举报
回复
引用 11 楼 hemowolf 的回复:
[quote=引用 9 楼 finemi 的回复:] 楼上几位,数据库的默认锁定机制,拿MYSQL来说,对于这种 先查询——》判断——》执行 的情况,我举的例子是否可以突破呢?
先判断,再执行,这个步骤是没问题的,也是一定要做的 问题是,你必须加锁 可以在你的程序里加上互斥锁,使用 synchronized 关键字 也可以在数据库里加锁,如果是mysql,可以写个存储过程,在过程里加锁,参考mysql的get_lock 函数 [/quote] 枷锁会影响程序性能,一般不建议用,除非你用户量小,访问量小..
pf_yin 2015-11-04
  • 打赏
  • 举报
回复
加锁或者防重,都能避免你这个问题
空心兜兜 2015-11-04
  • 打赏
  • 举报
回复
队列确实是个问题
小灰狼 2015-11-04
  • 打赏
  • 举报
回复
引用 9 楼 finemi 的回复:
楼上几位,数据库的默认锁定机制,拿MYSQL来说,对于这种 先查询——》判断——》执行 的情况,我举的例子是否可以突破呢?
先判断,再执行,这个步骤是没问题的,也是一定要做的 问题是,你必须加锁 可以在你的程序里加上互斥锁,使用 synchronized 关键字 也可以在数据库里加锁,如果是mysql,可以写个存储过程,在过程里加锁,参考mysql的get_lock 函数
younerest 2015-11-04
  • 打赏
  • 举报
回复
在代码段加锁或数据库端加锁
  • 打赏
  • 举报
回复
引用 9 楼 finemi 的回复:
楼上几位,数据库的默认锁定机制,拿MYSQL来说,对于这种 先查询——》判断——》执行 的情况,我举的例子是否可以突破呢?
If your lock works properly, it should be ok. As for mysql, make sure you have innodb as the engine, which support row level locking. https://dev.mysql.com/doc/refman/5.5/en/innodb-lock-modes.html
finemi 2015-11-03
  • 打赏
  • 举报
回复
楼上几位,数据库的默认锁定机制,拿MYSQL来说,对于这种 先查询——》判断——》执行 的情况,我举的例子是否可以突破呢?
  • 打赏
  • 举报
回复
引用 7 楼 u011643186 的回复:
这哥只要在jsp页面做一个防止重复提交就可以了。 或者后台加一个随机数来标识请求只能一次。
恩,这样也是一种处理方法
ab阿布 2015-11-03
  • 打赏
  • 举报
回复
这哥只要在jsp页面做一个防止重复提交就可以了。 或者后台加一个随机数来标识请求只能一次。
  • 打赏
  • 举报
回复
这种问题一直在讨论,并发,并发,并发! 数据持久层做乐观锁,业务方法进行事务控制,实在不行用消息队列,一个个排队搞,不过小心用户会投诉! 太慢了 哈哈
加载更多回复(5)

67,513

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧