Browse Source

分布式锁

yegang 2 years ago
parent
commit
ded554376b

+ 52 - 27
src/main/java/com/sw/service/impl/SnatchMaskServiceImpl.java

@@ -6,6 +6,9 @@ import com.sw.domain.TMask;
 import com.sw.service.SnatchMaskService;
 import com.sw.service.TMaskService;
 import com.sw.service.TOrderService;
+import lombok.extern.slf4j.Slf4j;
+import org.redisson.api.RLock;
+import org.redisson.api.RedissonClient;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.redis.core.RedisTemplate;
@@ -16,6 +19,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import javax.annotation.Resource;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.LockSupport;
 import java.util.concurrent.locks.ReentrantLock;
@@ -26,6 +30,7 @@ import java.util.concurrent.locks.ReentrantLock;
  * @Date 2022/2/18 13:22
  **/
 @Service
+@Slf4j
 public class SnatchMaskServiceImpl implements SnatchMaskService {
     @Autowired
     private TMaskService maskService;
@@ -39,6 +44,9 @@ public class SnatchMaskServiceImpl implements SnatchMaskService {
     @Resource
     private IMessageProducerService mqService;
 
+    @Autowired
+    private RedissonClient redissonClient;
+
     @Value("${amount}")
     private Integer amount;
     Object o = new Object();
@@ -76,18 +84,18 @@ public class SnatchMaskServiceImpl implements SnatchMaskService {
 
         reentrantLock.lock();
         try {
-           Integer remaining = Integer.valueOf(redisTemplate.opsForHash().get("usableMasks", "mask-" + mid).toString());
-           System.out.println("库存扣减前:" + remaining + "---" + Thread.currentThread());
-           if (remaining.compareTo(amount) >= 0) {
-               Long res = redisTemplate.opsForHash().increment("usableMasks", "mask-" + mid, -amount);
-               System.out.println("库存扣减后:" + "increment res : " + res + "---" + Thread.currentThread());//扣减之后的库存数量
-               return true;
-           } else {
-               return false;
-           }
-       } finally {
-           reentrantLock.unlock();
-       }
+            Integer remaining = Integer.valueOf(redisTemplate.opsForHash().get("usableMasks", "mask-" + mid).toString());
+            System.out.println("库存扣减前:" + remaining + "---" + Thread.currentThread());
+            if (remaining.compareTo(amount) >= 0) {
+                Long res = redisTemplate.opsForHash().increment("usableMasks", "mask-" + mid, -amount);
+                System.out.println("库存扣减后:" + "increment res : " + res + "---" + Thread.currentThread());//扣减之后的库存数量
+                return true;
+            } else {
+                return false;
+            }
+        } finally {
+            reentrantLock.unlock();
+        }
 
 
    /*     synchronized (o) {
@@ -122,22 +130,39 @@ public class SnatchMaskServiceImpl implements SnatchMaskService {
     @Override
     @Transactional
     public void doDecrAndCreateOrder(Integer uid, Integer maskId) {
-        //1.get the amount of remaining masks
-        TMask mask = maskService.getById(maskId);
-        System.out.println(mask.getMaskStock() + "----" + Thread.currentThread());
-        if (mask.getMaskStock() >= amount) {
-            //3.create order
-            int res = orderService.creatOrder(uid, maskId);
-            //4.decrease the stock of mask
-            Boolean flag = maskService.decrease(maskId, mask.getMaskStock() - amount);
-            if (res > 0 && flag) {
-
-                //3. add to successUserUids
-                redisTemplate.opsForSet().add("successUserUids", uid);
+        RLock lock = redissonClient.getLock("mask-" + maskId);
+        String threadName = Thread.currentThread().getName();
+        log.info("线程:{} 正在尝试获取锁。。。", threadName);
+        boolean b = false;
+        try {
+            b = lock.tryLock(3000, TimeUnit.MILLISECONDS);
+            if (b) {
+                //1.get the amount of remaining masks
+                TMask mask = maskService.getById(maskId);
+                System.out.println(mask.getMaskStock() + "----" + Thread.currentThread());
+                if (mask.getMaskStock() >= amount) {
+                    //3.create order
+                    int res = orderService.creatOrder(uid, maskId);
+                    //4.decrease the stock of mask
+                    Boolean flag = maskService.decrease(maskId, mask.getMaskStock() - amount);
+                    if (res > 0 && flag) {
+
+                        //3. add to successUserUids
+                        redisTemplate.opsForSet().add("successUserUids", uid);
+                    }
+                } else {
+                    // TODO 如果sql中库存不够 扣减失败之后 消息已经消费了 或者是事物回滚了  如何处理???
+                    return;
+                }
+                log.info("{}:业务执行完成", threadName);
+            } else {
+                log.info("{}:没有获取到锁,锁已被占用", threadName);
             }
-        } else {
-            // TODO 如果sql中库存不够 扣减失败之后 消息已经消费了 或者是事物回滚了  如何处理???
-            return;
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        } finally {
+            lock.unlock();
+            log.info("线程:{},释放了锁", threadName);
         }
     }
 }

+ 1 - 1
src/main/resources/redisson.yml

@@ -32,7 +32,7 @@ singleServerConfig:
   # 连接池大小
   connectionPoolSize: 1000
   # 数据库编号
-  database: 0
+  database: 4
   # DNS监测时间间隔,单位:毫秒
   dnsMonitoringInterval: 5000
 # 线程池数量,默认值: 当前处理核数量 * 2