欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java抽獎(jiǎng)?chuàng)屬?gòu)算法

 更新時(shí)間:2020年04月15日 15:28:48   作者:天藍(lán)1122  
這篇文章主要為大家詳細(xì)介紹了Java抽獎(jiǎng)?chuàng)屬?gòu)算法,ava實(shí)現(xiàn)的抽獎(jiǎng)?chuàng)屬?gòu)算法,用數(shù)據(jù)庫(kù)行鎖實(shí)現(xiàn),支持集群,感興趣的小伙伴們可以參考一下

本文示例為大家分享了Java抽獎(jiǎng)?chuàng)屬?gòu)算法,供大家參考,具體內(nèi)容如下

應(yīng)用場(chǎng)景

單件獎(jiǎng)品搶購(gòu)(可限時(shí))
多件獎(jiǎng)品按概率中獎(jiǎng)(可限時(shí)、可不限量)

代碼實(shí)現(xiàn)

表結(jié)構(gòu):

--抽獎(jiǎng)設(shè)置
create table AWARD_INFO
(
 ID   NUMBER(11) not null,
 ACT_ID  NUMBER(11), --活動(dòng)ID
 NUM  NUMBER(11), --獎(jiǎng)品總量(0為不限量)
 REST  NUMBER(11), --獎(jiǎng)品余量
 ODDS  NUMBER(11) default 0, --中獎(jiǎng)概率
 START_DATE DATE,   --開始日期(可為空)
 END_DATE DATE,   --結(jié)束日期(可為空)
 PRODUCT_ID NUMBER(11), --獎(jiǎng)品ID
 STATE  NUMBER(5) default 0, --狀態(tài) 0-有效 1-失效
 INFO_TYPE NUMBER(5) default 0  --0-正常 
);
alter table AWARD_INFO
 add constraint PK_AWARD_INFO primary key (ID);

--中獎(jiǎng)紀(jì)錄
create table AWARD_LOG
(
 id   number(11), 
 act_id  number(11), --活動(dòng)ID
 get_time date, --中獎(jiǎng)時(shí)間
 product_id number(11), --獎(jiǎng)品ID
 num  number(11) default 1, --中獎(jiǎng)數(shù)量
 person  varchar2(50), --中獎(jiǎng)人
 info_id number(11), --抽獎(jiǎng)設(shè)置ID
 state  number(5) --狀態(tài) 0-有效 1-失效
);
alter table AWARD_LOG
 add constraint PK_AWARD_LOG primary key (ID);

代碼:

 public static class AwardResult{
  public int ret; //返回結(jié)果
  public int logId; //AWARD_LOG id
 }

 /**
  * 抽獎(jiǎng)算法
  * @param actId 抽獎(jiǎng)活動(dòng)ID
  * @param person 抽獎(jiǎng)人
  * @param productId 獎(jiǎng)品ID -1則為該活動(dòng)ID下所有獎(jiǎng)品
  * @param excludeId 排除獎(jiǎng)品ID -1 則不排除,與productId不能同時(shí)>0
  * @param checkDate 是否檢查時(shí)間
  * @return -1 沒有抽獎(jiǎng)數(shù)據(jù);-2 獎(jiǎng)品已抽完; -3 其他錯(cuò)誤;>=0 中獎(jiǎng)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){//搶購(gòu)
    sql = baseSql + " and t.product_id=? " + checkDateStr + " for update";
    rows = JDBC.getRows(sql, new Object[]{actId, productId}, conn);
   }else{//活動(dòng)所有物品抽獎(jiǎng)
    sql = baseSql + checkDateStr + " for update";
    rows = JDBC.getRows(sql, new Object[]{actId}, conn);
   }

   if(rows.isEmpty()){//沒有抽獎(jiǎng)數(shù)據(jù)
    log.info("沒有抽獎(jiǎng)數(shù)據(jù) 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){//搶購(gòu)
    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{//抽獎(jiǎng)
    int[][] temp = new int[rows.size()][3];
    int sum = -1;
    int i = 0;
    for(int k = 0; k < rows.size(); k++){//設(shè)置獎(jiǎng)品池
     int odds = ((BigDecimal)rows.get(k).get("ODDS")).intValue();
     sum++;
     temp[i][0] = sum; //起始值
     sum = sum + odds;
     temp[i][1] = sum; //結(jié)束值
     temp[i][2] = k; //rows index
     i++;
    }
    //抽獎(jiǎng)
    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("獎(jiǎng)品已清空 actId={} person={} productId={} excludeIds={} checkDate={}", actId, person, productId, excludeIds, checkDate);
    JDBC.commit(conn);
    result.ret = -2;
    return result;
   }

   //更新獎(jiǎng)品記錄
   if(num > 0){//非不限量
    sql = "update award_info set rest = rest - 1 where id = ?";
    JDBC.update(sql, new Object[]{infoId}, conn);
   }

   //記錄獲獎(jiǎng)名單
   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;
}

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • JAVA語法糖原理你知道嗎

    JAVA語法糖原理你知道嗎

    語法糖(Syntactic sugar),也叫做糖衣語法,是英國(guó)科學(xué)家發(fā)明的一個(gè)術(shù)語,通常來說使用語法糖能夠增加程序的可讀性,從而減少程序代碼出錯(cuò)的機(jī)會(huì).這篇文章主要介紹了Java 中的語法糖知識(shí),需要的朋友可以參考下
    2021-09-09
  • 解決mybatis中resultType取出數(shù)據(jù)順序不一致的問題

    解決mybatis中resultType取出數(shù)據(jù)順序不一致的問題

    這篇文章主要介紹了解決mybatis中resultType取出數(shù)據(jù)順序不一致的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • idea如何解決maven依賴沖突

    idea如何解決maven依賴沖突

    這篇文章主要介紹了idea如何解決maven依賴沖突問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • java Wrapper類基本用法詳解

    java Wrapper類基本用法詳解

    在本篇文章里小編給大家整理的是一篇關(guān)于java Wrapper類基本用法詳解,有興趣的朋友們可以參考下。
    2021-01-01
  • 淺析JAVA Lock鎖原理

    淺析JAVA Lock鎖原理

    這篇文章主要介紹了JAVA Lock鎖原理的相關(guān)資料,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • SpringMVC通過攔截器實(shí)現(xiàn)IP黑名單

    SpringMVC通過攔截器實(shí)現(xiàn)IP黑名單

    這篇文章主要為大家詳細(xì)介紹了SpringMVC通過攔截器實(shí)現(xiàn)IP黑名單,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • javascript與jsp發(fā)送請(qǐng)求到servlet的幾種方式實(shí)例

    javascript與jsp發(fā)送請(qǐng)求到servlet的幾種方式實(shí)例

    本文分別給出了javascript發(fā)送請(qǐng)求到servlet的5種方式實(shí)例與 jsp發(fā)送請(qǐng)求到servlet的6種方式實(shí)例
    2018-03-03
  • java中ThreadLocal取不到值的兩種原因

    java中ThreadLocal取不到值的兩種原因

    這篇文章主要介紹了java中ThreadLocal取不到值的兩種原因,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • 詳解使用JavaCV/OpenCV抓取并存儲(chǔ)攝像頭圖像

    詳解使用JavaCV/OpenCV抓取并存儲(chǔ)攝像頭圖像

    本篇文章主要介紹了使用JavaCV/OpenCV抓取并存儲(chǔ)攝像頭圖像,實(shí)例分析了使用JavaCV/OpenCV抓取并存儲(chǔ)攝像頭圖像的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2017-04-04
  • Java中List、Set、Map的區(qū)別和實(shí)現(xiàn)方式示例代碼

    Java中List、Set、Map的區(qū)別和實(shí)現(xiàn)方式示例代碼

    這篇文章主要介紹了Java中List、Set、Map的區(qū)別和實(shí)現(xiàn)方式示例代碼,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-06-06

最新評(píng)論