Java抽奖抢购算法
本文示例为大家分享了Java抽奖抢购算法,供大家参考,具体内容如下
应用场景
单件奖品抢购(可限时)
多件奖品按概率中奖(可限时、可不限量)
代码实现
表结构:
--抽奖设置 createtableAWARD_INFO ( IDNUMBER(11)notnull, ACT_IDNUMBER(11),--活动ID NUMNUMBER(11),--奖品总量(0为不限量) RESTNUMBER(11),--奖品余量 ODDSNUMBER(11)default0,--中奖概率 START_DATEDATE,--开始日期(可为空) END_DATEDATE,--结束日期(可为空) PRODUCT_IDNUMBER(11),--奖品ID STATENUMBER(5)default0,--状态0-有效1-失效 INFO_TYPENUMBER(5)default0--0-正常 ); altertableAWARD_INFO addconstraintPK_AWARD_INFOprimarykey(ID); --中奖纪录 createtableAWARD_LOG ( idnumber(11), act_idnumber(11),--活动ID get_timedate,--中奖时间 product_idnumber(11),--奖品ID numnumber(11)default1,--中奖数量 personvarchar2(50),--中奖人 info_idnumber(11),--抽奖设置ID statenumber(5)--状态0-有效1-失效 ); altertableAWARD_LOG addconstraintPK_AWARD_LOGprimarykey(ID);
代码:
publicstaticclassAwardResult{ publicintret;//返回结果 publicintlogId;//AWARD_LOGid } /** *抽奖算法 *@paramactId抽奖活动ID *@paramperson抽奖人 *@paramproductId奖品ID-1则为该活动ID下所有奖品 *@paramexcludeId排除奖品ID-1则不排除,与productId不能同时>0 *@paramcheckDate是否检查时间 *@return-1没有抽奖数据;-2奖品已抽完;-3其他错误;>=0中奖productId;-4排除id *@throwsException */ publicstaticAwardResultgetAwardFull(intactId,Stringperson,intproductId,int[]excludeIds,booleancheckDate)throwsSQLException{ AwardResultresult=newAwardResult(); Connectionconn=JDBC.getConnection(); conn.setAutoCommit(false); try{ List<Map<String,Object>>rows; Stringsql; StringcheckDateStr=""; StringbaseSql="selectt.id,t.product_id,t.num,t.rest,t.odds,t.info_typefromaward_infotwheret.act_id=?andt.state=0"; if(checkDate){ checkDateStr="andt.start_Date<=sysdateandt.end_Date>=sysdate"; } if(productId>0){//抢购 sql=baseSql+"andt.product_id=?"+checkDateStr+"forupdate"; rows=JDBC.getRows(sql,newObject[]{actId,productId},conn); }else{//活动所有物品抽奖 sql=baseSql+checkDateStr+"forupdate"; rows=JDBC.getRows(sql,newObject[]{actId},conn); } if(rows.isEmpty()){//没有抽奖数据 log.info("没有抽奖数据actId={}person={}productId={}excludeIds={}checkDate={}",actId,person,productId,excludeIds,checkDate); conn.commit(); result.ret=-1; returnresult; } intinfoId=-1; intgetProductId=-1; intnum=-1; intrest=-1; if(rows.size()==1){//抢购 num=((Number)rows.get(0).get("NUM")).intValue(); rest=((Number)rows.get(0).get("REST")).intValue(); infoId=((Number)rows.get(0).get("ID")).intValue(); getProductId=((Number)rows.get(0).get("PRODUCT_ID")).intValue(); }else{//抽奖 int[][]temp=newint[rows.size()][3]; intsum=-1; inti=0; for(intk=0;k<rows.size();k++){//设置奖品池 intodds=((BigDecimal)rows.get(k).get("ODDS")).intValue(); sum++; temp[i][0]=sum;//起始值 sum=sum+odds; temp[i][1]=sum;//结束值 temp[i][2]=k;//rowsindex i++; } //抽奖 Randomrandom=newRandom(); intr=random.nextInt(sum+1); intj=0; for(intk=0;k<i;k++){ if(r>=temp[k][0]&&r<=temp[k][1]){ j=k; break; } } infoId=((BigDecimal)rows.get(temp[j][2]).get("ID")).intValue(); getProductId=((BigDecimal)rows.get(temp[j][2]).get("PRODUCT_ID")).intValue(); num=((Number)rows.get(temp[j][2]).get("NUM")).intValue(); rest=((Number)rows.get(temp[j][2]).get("REST")).intValue(); } //判断是否排除id if(ArrayUtils.contains(excludeIds,getProductId)){ log.info("是排除IDactId={}person={}productId={}excludeIds={}checkDate={}",actId,person,productId,excludeIds,checkDate); conn.commit(); result.ret=-4; returnresult; } //存量不足 if(num>0&&rest<=0){ log.info("奖品已清空actId={}person={}productId={}excludeIds={}checkDate={}",actId,person,productId,excludeIds,checkDate); JDBC.commit(conn); result.ret=-2; returnresult; } //更新奖品记录 if(num>0){//非不限量 sql="updateaward_infosetrest=rest-1whereid=?"; JDBC.update(sql,newObject[]{infoId},conn); } //记录获奖名单 AwardLoglog=newAwardLog(); log.setActId(actId); log.setNum(1); log.setPerson(person); log.setProductId(getProductId); log.setInfoId(infoId); NumberlogId=log.save(conn); if(logId==null){ thrownewSQLException("saveaward_logerror"); } result.logId=logId.intValue(); conn.commit(); result.ret=getProductId; returnresult; }catch(SQLExceptione){ log.error("getAwarderror",e); conn.rollback(); }finally{ JDBC.close(conn); } result.ret=-3; returnresult; }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。