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;
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。