一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - Java抽獎搶購算法

Java抽獎搶購算法

2020-06-02 11:13天藍1122 JAVA教程

這篇文章主要為大家詳細介紹了Java抽獎搶購算法,ava實現的抽獎搶購算法,用數據庫行鎖實現,支持集群,感興趣的小伙伴們可以參考一下

本文示例為大家分享了Java抽獎搶購算法,供大家參考,具體內容如下

應用場景

單件獎品搶購(可限時)
多件獎品按概率中獎(可限時、可不限量)

代碼實現

表結構:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
--抽獎設置
create table AWARD_INFO
(
 ID   NUMBER(11) not null,
 ACT_ID  NUMBER(11), --活動ID
 NUM  NUMBER(11), --獎品總量(0為不限量)
 REST  NUMBER(11), --獎品余量
 ODDS  NUMBER(11) default 0, --中獎概率
 START_DATE DATE,   --開始日期(可為空)
 END_DATE DATE,   --結束日期(可為空)
 PRODUCT_ID NUMBER(11), --獎品ID
 STATE  NUMBER(5) default 0, --狀態 0-有效 1-失效
 INFO_TYPE NUMBER(5) default --0-正常
);
alter table AWARD_INFO
 add constraint PK_AWARD_INFO primary key (ID);
 
--中獎紀錄
create table AWARD_LOG
(
 id   number(11),
 act_id  number(11), --活動ID
 get_time date, --中獎時間
 product_id number(11), --獎品ID
 num  number(11) default 1, --中獎數量
 person  varchar2(50), --中獎人
 info_id number(11), --抽獎設置ID
 state  number(5) --狀態 0-有效 1-失效
);
alter table AWARD_LOG
 add constraint PK_AWARD_LOG primary key (ID);

代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
public static class AwardResult{
  public int ret; //返回結果
  public int logId; //AWARD_LOG id
 }
 
 /**
  * 抽獎算法
  * @param actId 抽獎活動ID
  * @param person 抽獎人
  * @param productId 獎品ID -1則為該活動ID下所有獎品
  * @param excludeId 排除獎品ID -1 則不排除,與productId不能同時>0
  * @param checkDate 是否檢查時間
  * @return -1 沒有抽獎數據;-2 獎品已抽完; -3 其他錯誤;>=0 中獎productId; -4 排除id
  * @throws Exception
  */
 public static AwardResult getAwardFull(int actId, String person, int productId, int[] excludeIds, boolean checkDate) throws SQLException{
  AwardResult result = new AwardResult();
 
  Connection conn = JDBC.getConnection();
  conn.setAutoCommit(false);
  try{
   List<Map<String,Object>> rows;
   String sql;
   String checkDateStr = "";
   String baseSql = "select t.id, t.product_id, t.num, t.rest, t.odds, t.info_type from award_info t where t.act_id=? and t.state=0 ";
   if(checkDate){
    checkDateStr = " and t.start_Date <= sysdate and t.end_Date >= sysdate ";
   }
   if(productId > 0){//搶購
    sql = baseSql + " and t.product_id=? " + checkDateStr + " for update";
    rows = JDBC.getRows(sql, new Object[]{actId, productId}, conn);
   }else{//活動所有物品抽獎
    sql = baseSql + checkDateStr + " for update";
    rows = JDBC.getRows(sql, new Object[]{actId}, conn);
   }
 
   if(rows.isEmpty()){//沒有抽獎數據
    log.info("沒有抽獎數據 actId={} person={} productId={} excludeIds={} checkDate={}", actId, person, productId, excludeIds, checkDate);
    conn.commit();
    result.ret = -1;
    return result;
   }
   int infoId = -1;
   int getProductId = -1;
   int num = -1;
   int rest = -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 = new int[rows.size()][3];
    int sum = -1;
    int i = 0;
    for(int k = 0; k < rows.size(); k++){//設置獎品池
     int odds = ((BigDecimal)rows.get(k).get("ODDS")).intValue();
     sum++;
     temp[i][0] = sum; //起始值
     sum = sum + odds;
     temp[i][1] = sum; //結束值
     temp[i][2] = k; //rows index
     i++;
    }
    //抽獎
    Random random = new Random();
 
    int r = random.nextInt(sum + 1);
    int j = 0;
    for(int k = 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("是排除ID actId={} person={} productId={} excludeIds={} checkDate={}", actId, person, productId, excludeIds, checkDate);
    conn.commit();
    result.ret = -4;
    return result;
   }
 
   //存量不足
   if(num > 0 && rest <= 0){
    log.info("獎品已清空 actId={} person={} productId={} excludeIds={} checkDate={}", actId, person, productId, excludeIds, checkDate);
    JDBC.commit(conn);
    result.ret = -2;
    return result;
   }
 
   //更新獎品記錄
   if(num > 0){//非不限量
    sql = "update award_info set rest = rest - 1 where id = ?";
    JDBC.update(sql, new Object[]{infoId}, conn);
   }
 
   //記錄獲獎名單
   AwardLog log = new AwardLog();
   log.setActId(actId);
   log.setNum(1);
   log.setPerson(person);
   log.setProductId(getProductId);
   log.setInfoId(infoId);
   Number logId = log.save(conn);
   if(logId == null){
    throw new SQLException("save award_log error");
   }
   result.logId = logId.intValue();
 
   conn.commit();
   result.ret = getProductId;
   return result;
 
  }catch(SQLException e){
   log.error("getAward error", e);
   conn.rollback();
  }finally{
   JDBC.close(conn);
  }
  result.ret = -3;
  return result;
}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: japan日韩xxxx69hd japanese在线观看 | 毛片在线观看网站 | 99热.com| 欧美在线一| 男女啪啪gif | 精油按摩日本 | 风间由美一区二区播放合集 | 日本一级不卡一二三区免费 | 日本精a在线观看 | 大象传媒2021秘密入口 | 成人国产精品一区二区不卡 | 亚洲欧洲日产国码无码av | 日本b站一卡二不卡三卡四卡 | 情人梁家辉在线 | 秀婷程仪公欲息肉婷在线观看 | 亚洲3dxxxx动漫xxx| 出轨同学会2在线观看 | 99热在线免费观看 | 污斗罗大陆 | 亚洲国产成人精品激情 | 国产欧美日韩成人 | 99热精品在线免费观看 | 日本大片免a费观看在线 | 狠狠色成人综合 | 亚洲香蕉网久久综合影院3p | 超级碰碰免费视频 | 国产一区二区精品 | 亚洲精品中文字幕在线 | 久久偷拍国2017的 | 九九国产视频 | 99国产国人青青视频在线观看 | 欧美男人天堂 | 国产成人高清精品免费5388密 | 亚州成人| 久久这里有精品 | 日韩欧美一区二区三区免费观看 | 日韩性大片免费 | 波多野结衣久久国产精品 | 干露露视频 性感写真 | 日韩欧美亚洲每日更新网 | 果冻传媒在线视频播放观看 |