锁定老帖子 主题:php同步方案2-飞机票问题
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-10-06
最后修改:2011-10-06
请注意:以下解决方案要求mysql表引擎必须是innodb。 $db = getdb(); $db->query('SET AUTOCOMMIT=0'); $db->query('START TRANSACTION'); $sql = " select id from air_ticket where isactive=1 and batch='today' for update";//查今天的有效飞机票,for update 是重点。 $result = $db->fetchOne($sql); //因为顾客只想买一张票 if ($result) { //还有票 $db->query("update air_ticket set isactive=0 where batch='today' and id=". $result); //发了一张票 } $db->query('COMMIT'); $db->query('SET AUTOCOMMIT=1'); if ($result) { echo "您购买的机票id是".$result; } else { echo '对不起,机票已卖完'; } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-10-07
最后修改:2011-10-07
还有一种做法,乐观法:
开启事务: 直接减1, 检查剩余机票是否是负数。 如果是回滚,并告诉用户错误。 如果不是,提交事务。 不过这个做法有并发的隐患,不好,只能用于允许一些错误的场合。 可能要把事务隔离级别设为不可重复读,或脏读以看到别的事务的修改。 |
|
返回顶楼 | |
发表时间:2011-10-07
同步方案一的方法是同步,for update的方法是用innodb的行锁。
究竟该用哪种,取决于项目中的别的代码。 如果操作机票表只有很少的几个文件,可以同步 如果操作机票表只有文件很多,同步不过来(因为那样系统太卡了),只能行锁。 如果写操作并发少,行锁, 写操作并发多,行锁会影响别的写操作,那么同步可以。 (针对这一点,如果用行锁,需要适当分表) 需要同步的代码很少,系统能很快执行完,优先同步,同步正确率应该高,理论上是这样。 反之只能行锁。 |
|
返回顶楼 | |
发表时间:2011-10-08
for update
|
|
返回顶楼 | |
发表时间:2011-10-10
剩一张票了,两个请求同时到来。
把两个请求放到队列中。先到先得。 |
|
返回顶楼 | |
发表时间:2011-10-10
jinhanjiang 写道 剩一张票了,两个请求同时到来。
把两个请求放到队列中。先到先得。 是的 这个时候就可以玩玩NODE JS |
|
返回顶楼 | |
发表时间:2011-10-10
mysql 高版本可以用这个来模拟排队
SELECT GET_LOCK |
|
返回顶楼 | |
发表时间:2011-10-10
jinhanjiang 写道 剩一张票了,两个请求同时到来。
把两个请求放到队列中。先到先得。 一般来说订机票要立刻看到结果,就是不异步,那么实际上还是同步了。 同步 的情况就跟调用mysql的get_lock差不多。 |
|
返回顶楼 | |
发表时间:2011-10-13
for update很容易造成死锁,不建议用
如果允许失败,可以这样 $db->query("update air_ticket set isactive=0 where batch='today' and isactive=1 and id=". $result); update时增加 isactive=1 |
|
返回顶楼 | |
发表时间:2011-10-14
synchronized
|
|
返回顶楼 | |