售票并发解决方案
今天找以前的笔记,突然发现这篇,遥记是去年在一家主营代理各种点卡在线充值的公司问的面试题。
以前从没做过悲观并发方面的,一时想不出看起来可行的解决方案。加上面试的人非要我在那台放打印机边的烂公共电脑上上机,
于是走了。在公交车上对并发售票的问题念念不忘,在手机上写了篇笔记。这次还能找到,就拿出来放这里当笔记,要是还放电脑上,
不知很年月能再发现。以下为思索过程:
一,购票大致流程:
1,读取所有可买票(where state=可买)
2,买的过程:
2.0查询余票
2.1点击购买
2.2 中间各种蹉跎
2.3 最后一步做完
2.4放弃。
二,数据库端设计
1,一类票本来可以用一行数据来记录,但是为了支持更高的并发,可以分拆成n条记录,比如1w张,分成100行,则每行有100条记录。只使用行级锁的时候,提高的并发度非常客观。假设记录数量的字段叫TicketCount。
2,每条记录多加一个字段用来记录已开始点击购买但是尚未完成购买的数量,例如名字叫OrderingCount。
3,服务端设任务管理器
三,详细过程
2.0 采用top one,条件是可卖((TicketCount-OrderingCount>0),若取不到top one,则告知刚刚卖光。
返回该条的key.
2.1
a,key+用户初始化一个任务,添加到任务管理器,开始计时该条任务。
b,update 数据库记录中的OrderingCount
2.2,倒计时任务,如果时间到,则提示购买超时,update回数据库记录中的OrderingCount。或是其他策略,比如只是回退OrderingCount,把机会让出来,若是客户最后还是走到了2.3,则再试试2.0,看是否还可以买。
2.3
a,update回数据库记录中的OrderingCount,TicketCount.
b,任务管理器标志任务完成,并做其他销毁动作。
2.4
a,update回退数据库记录中的OrderingCount.
b,任务管理器标志任务完成,并做其他销毁动作。
一些小细节也许需要更多斟酌,但是要大致解决提高并发,支持业务中的长事务,在大方向上应该是可以了。
尚未测试,以后来写段测试程序看看。