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