领取红包时,如何防多线程时重复领取

今天公司做一个三周年活动领取红包的接口,我先把我的想法表述一下(撇除业务逻辑)

  • 往红包表里insert一条记录,通过实体类中的用户id(customerId)字段以及红包类型(type)字段,来保证数据的唯一性
  • 每次insert之前都会去红包表里面查询是否已经有记录了(根据customerId和type),如果有记录就说明领取过了。

写完之后测了几下没问题,push了代码。

问题来了,当多个线程携带同个sessionToken访问该url时,就会出现插入多条记录的情况,测试代码如下:

public class ThreadRunner implements Runnable {

    @Override
    public void run() {
        //String url="http://localhost:8085/gamecenter/anniversary/getWelfare?sessionToken=S3BJVUNOVGI2VHRFYmhkdkFGaFlRWjRrZDNHTzE0NXg";
//        String url="http://18.10.1.35:8085/gamecenter/anniversary/getWelfare?sessionToken=TlZqWEJjU1lMSmRkaEhESGNRR21KSW51WFJmdkRmc0o";
        String url = "http://18.10.1.35:8085/gamecenter/anniversary/getWelfare?sessionToken=RHBBVktOam1IZDNHSjRvTnJURElvQ3d6SHJjQlFsTUc";
        System.out.println(HttpClientUtil.sendGet(url));
    }

    public static void main(String[] args) {
        ExecutorService pool = Executors.newFixedThreadPool(10);
        for(int i = 0 ; i < 10 ; i++){
            pool.submit(new ThreadRunner());
        }
        pool.shutdown();
    }
}

解决方法:

新建一张customerId为主键的表——temp,每次往红包表里面insert之前都往temp表里面insert一条,如果insert成功再去红包表里面insert记录。

否则提示“领取失败!

用同样的方法再测一下。结果如下,当多个线程时,就只会领取一次了。

总结:第一次写博客,语言比较笨拙,对于这种问题的解决方法也比较low,比较麻烦,各位看官如果有什么好的方法欢迎留言!

谢谢观看!

猜你喜欢

转载自www.cnblogs.com/qinshuxiu/p/9361635.html