Redis 分布式锁

/ 3评 / 0

    说起来有些尴尬。最近写了一个抽奖发券的功能,因为是100%中奖,倒是抽奖没怎么折腾。但是问题在于返券。

    大致规则是这样子的:在活动期间每人每支付一个订单,就可以获取一次抽奖机会,而最多可以抽十次奖,抽奖之后得把奖品发放。

    分析需求之后就变得很简单,无非是拉取符合条件的订单数,然后计算抽奖机会,满足则可抽奖,抽完奖同步中奖纪录,然后发放奖品。的确在流程上也没什么问题,主要注意同步中奖信息时的事物就好。这样一来只需要在方法上加上@Transactional注解就好了。

    然后三下五除二搞定了,开始自己本地测试,也没啥问题。于是匆匆上了测试库。

    过了一会前端告诉我他抽奖抽了十二次。我告诉他不可能了。十次的时候就会有check,你连正常访问都做不到。然后打开DB一查还真是。。于是我开始重新审视我的逻辑。但毕竟一个流程清晰的抽奖,在业务上不会犯这种奇怪的逻辑错误。

    然后看了下DB插入时间,我似乎明白了啥。。于是我写了小的测试:

     然后一个人拿着一次的抽奖机会,抽中了七个奖品(我的次数check逻辑是通过奖品记录表来反减的

    然后我就想给这方法加锁。于是给方法加上了synchronized。这一幕被同事大哥给看见了。他问我我们的项目上锁别用这个,服务器有很多台,分布式的,你这个太鬼畜了。

    我一想??那分布式锁如何实现?同事给我一条明路:

    利用Redis快速起了一个分布式锁,完美解决了上面的问题,这样只需在方法执行前加上加锁的过程:

        这样除了事务的保护之外还有针对并发的处理,问题就被解决了(对了,在此之前记得配置Namespce以及Spring的Bean注入。差点。。感谢前端的光速请求)

    期间顺便参观了下别人的用法:

    https://blog.csdn.net/he90227/article/details/69568702#t0



3条回应:“Redis 分布式锁”

  1. Nostring说道:

    现在回看这种方案的使用,利用Redis做锁原则上可行,但是在效率和资源上我觉得还是自己真的土豪,居然拿这个去锁一个方法,其实这里不应该在使用这样的设计思路去设计。虽然思路简单实现简单,但是生产环境不推荐这样去做。

发表评论

电子邮件地址不会被公开。 必填项已用*标注