Code Bye

java怎么样高并发处理mysql中的有限资源(车票、优惠券等)

业务场景:
有不同种类的优惠券,用户领取优惠券也有限制,活动期限领或每日限领。
领取过程有以下几个步骤:
1、查询优惠券表cp_info,能否有剩余;
2、查询用户能否已经领取过了,表cp_draw_details中能否有记录(若每日限领,会根据领取时间进行过滤)
3、若可以领取,表cp_draw_details中插入一条记录,表cp_info中更新剩余数量
上午查mysql有行锁和表锁,还有查询时使用for update进行锁定(查询条件的字段是索引字段,才会行锁,否则表锁)。
不清楚java代码中是不是也要加synchronized同步块。
当前是在领取时,将领取过程写在一个synchronized同步块中,知道这样效率十分低,最近也正在考虑怎么样处理。
有知道怎么样优化的可以说一下思路。
解决方案

15

LZ你好
架构这种事情,除非很了解业务的人,否则无法给出切实有效的解决方案,下面这篇文档希望能够帮助你
http://www.cnblogs.com/javathread/archive/2012/01/10/2634963.html

25

引用 2 楼 nyhyn 的回复:

谢谢你的回答,看过你发的那篇文章,也很有启发。
本人本人做过一个测试,使用select  … for update,若查询条件字段是索引,会锁住这条记录。需要使用ENGINE=InnoDB。
在整个事务处理完后,其他事务才可以更新这条记录。
当前只有表添加一个标志字段,第一个查询来时将其置为1,后面的就查询不到等待。处理完后再 置为0。这样就不至于将全部优惠券都放在同一个synchronized块中。
欢迎感兴趣和有其他解决思路的一起探讨。

这种对于资源的获取问题,原因是你的资源实际上就是数据库中的记录,所以这种锁,可以放到数据库中来实现,通过加上for update,也就是在查询数据的时候,通过索引,就对那一个记录加上独占锁,一方面避免了表锁,也避免了多线程并发访问数据时,产生不一致的问题。


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明java怎么样高并发处理mysql中的有限资源(车票、优惠券等)