激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

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

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;
}

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 成人一区二区三区四区 | 99精品视频久久精品视频 | 成人三级电影网址 | 国产一区二区三区四区波多野结衣 | 免费视频xxxx| 一区二区三区在线观看免费视频 | 亚洲影视中文字幕 | 粉嫩蜜桃麻豆免费大片 | 国产精品久久99精品毛片三a | 国产毛片在线 | 女教师~淫辱の动漫在线 | 日本黄色免费片 | 国产日韩中文字幕 | 欧美亚成人 | 在线播放免费人成毛片乱码 | 污视频在线看 | 色操网 | 91精品国产一区二区在线观看 | 一级黄色影院 | 欧美精品38videos性欧美 | 亚洲成人精品视频 | 一区二区国产在线 | 91av在线免费视频 | 久草资源在线观看 | 亚洲成人精品视频 | 欧美精品一区二区久久 | 三级国产三级在线 | 久久久噜噜噜久久熟有声小说 | 欧美一级视频在线观看 | 9999在线视频 | 91午夜免费视频 | 国产成人高清成人av片在线看 | 伊人手机在线观看 | 羞羞视频免费入口网站 | 欧美日韩艺术电影在线 | av电影直播| 亚洲少妇诱惑 | 欧美日性 | 毛片118极品美女写真 | 久久免费视屏 | 久久久久电影网站 |