update 表名 set 数量字段-=1 where 商品id=id and 数量字段>0
返回影响行数为1则发放成功.为0则失败.
我的数据库设计是有一个奖品表,表中有奖品名称,等级,一共发放数量,每天发放数量,已经中奖的数量,还有一个抽奖记录表,所有的数据都记录,如果抽中奖品就更新奖品表中的中奖数量,如果中奖数量大于等于每天发放数量就不在发放,概率就为零了.所以感觉不适用啊
@tanhao09: ,如果抽中奖品就更新奖品表中的中奖数量,如果中奖数量大于等于每天发放数量就不在发放
你这样看觉得适用不?而且我说的只是在update语句的条件中加上 合理 的限制条件来解决并发问题.
@吴瑞祥: 应该能适用,但是如果我这个奖品的当天的总发放量是20,在开始的时候查询时是19个,在程序运行的过程中另一个程序更新了数据库为20,那么我这一条就失败了,可是事实上这个人已经抽中了奖品,有抽中奖记录,只是没有更新成功.他在我的奖品中也能看到,那么我是不是需要把抽奖记录的插入顺序和更新的顺序改变一下,先更新更新成功再插入记录,否则记录也不插入?
@tanhao09: 所以你要在事务里操作.然后根据update条件更新结果判断事务是否成功.
我改了一下代码理论上是解决了但是我还是想多问点其他的方法,拓展一下知识面,我在网上找过一种方法是用利用redis的原子性,将奖品总数是20分成多少20份,放在redis的一个列表中,中一个取出一个,当列表中没有时,不在发放,或者将中奖数放在redis中,中一个,取出中奖数,和总数判断有没有超出,没有相加,超出不在相加,同时不在返回.楼上的时间戳的方法我没有弄明白.
@tanhao09: redis的原子性..怕不是活在梦里..
你可以百度下:sql数据库事务的特性.总的来说并发问题处理确实是靠原子性保证来做的.
数据库支持是最好的.
@吴瑞祥: 好的,受教了,我回头仔细看看,谢谢了
给数据库记录增加时间戳,更新的时候,带上时间戳条件。如果中途有人更新过,那么你会更新失败。
我的数据库设计是有一个奖品表,表中有奖品名称,等级,一共发放数量,每天发放数量,已经中奖的数量,还有一个抽奖记录表,所有的数据都记录,如果抽中奖品就更新奖品表中的中奖数量,如果中奖数量大于等于每天发放数量就不在发放,概率就为零了.所以感觉不适用啊
我又查了一下相关的资料,您的意思是不是在开头查询记录,记录带时间戳的字段,在更新的时候带上update 表名中奖数量加1and update_time=查询的时间戳, 如果中间没有被更改过就更新,更改过就不更新?可是这样的话,如果别人更改了,我这条数据不就不能更新了吗?
@tanhao09: 是指你在查询数量和提交更改后的数量之前,没有其他人操作(保证数量是准确的)。
你的问题是 两个客户端,访问同一个数据库,两个客户端同时增删改查,有可能造成一个数据同时进行操作的问题?
对,是这样的