Authored by chenchao

use cas lock

1 package com.yohoufo.order.service.impl; 1 package com.yohoufo.order.service.impl;
2 2
  3 +import com.google.common.base.Throwables;
3 import com.google.common.collect.Lists; 4 import com.google.common.collect.Lists;
4 import com.yoho.core.dal.datasource.annotation.Database; 5 import com.yoho.core.dal.datasource.annotation.Database;
5 import com.yohobuy.ufo.model.order.bo.ButtonShowBo; 6 import com.yohobuy.ufo.model.order.bo.ButtonShowBo;
@@ -32,6 +33,8 @@ import com.yohoufo.order.service.proxy.ProductProxyService; @@ -32,6 +33,8 @@ import com.yohoufo.order.service.proxy.ProductProxyService;
32 import com.yohoufo.order.service.proxy.SellerNoticeFacade; 33 import com.yohoufo.order.service.proxy.SellerNoticeFacade;
33 import com.yohoufo.order.service.seller.SkupService; 34 import com.yohoufo.order.service.seller.SkupService;
34 import com.yohoufo.order.utils.LoggerUtils; 35 import com.yohoufo.order.utils.LoggerUtils;
  36 +import lombok.AllArgsConstructor;
  37 +import lombok.Data;
35 import org.apache.commons.collections.CollectionUtils; 38 import org.apache.commons.collections.CollectionUtils;
36 import org.slf4j.Logger; 39 import org.slf4j.Logger;
37 import org.springframework.beans.factory.annotation.Autowired; 40 import org.springframework.beans.factory.annotation.Autowired;
@@ -261,11 +264,18 @@ public class DepositServiceImpl implements DepositService { @@ -261,11 +264,18 @@ public class DepositServiceImpl implements DepositService {
261 LOGGER.info("changeSaleStatusOn uid {}, depositCode is {}, skup is {}", uid, depositCode, skup); 264 LOGGER.info("changeSaleStatusOn uid {}, depositCode is {}, skup is {}", uid, depositCode, skup);
262 boolean result = storageDepositMapper.changeSaleStatusOn(uid, depositCode, skup) == 1; 265 boolean result = storageDepositMapper.changeSaleStatusOn(uid, depositCode, skup) == 1;
263 if (result) { 266 if (result) {
264 - StorageDeposit sd = storageDepositMapper.queryByDepositCode(uid, depositCode);  
265 - clearCache(uid, sd.getProductId(), sd.getStorageId()); 267 + cleanCacheWhenOnShelve(uid, depositCode);
  268 + //unlock
  269 + new DepositLock(uid, depositCode).unlock();
266 } 270 }
267 return result; 271 return result;
268 } 272 }
  273 +
  274 + private void cleanCacheWhenOnShelve(Integer uid, String depositCode){
  275 + StorageDeposit sd = storageDepositMapper.queryByDepositCode(uid, depositCode);
  276 + clearCache(uid, sd.getProductId(), sd.getStorageId());
  277 + }
  278 +
269 // 下架 279 // 下架
270 @Override 280 @Override
271 @Database(ForceMaster=true) 281 @Database(ForceMaster=true)
@@ -295,23 +305,34 @@ public class DepositServiceImpl implements DepositService { @@ -295,23 +305,34 @@ public class DepositServiceImpl implements DepositService {
295 305
296 // 批量上架 306 // 批量上架
297 public List<StorageDeposit> changeSaleStatusOnBatch(Integer uid, Integer storageId, List<Integer> skupList) { 307 public List<StorageDeposit> changeSaleStatusOnBatch(Integer uid, Integer storageId, List<Integer> skupList) {
298 - int count = skupList.size();  
299 - List<StorageDeposit> sdList = storageDepositMapper.getDepositOffs(uid, storageId, count);  
300 - List<StorageDeposit> successList = new ArrayList<>();  
301 - for (int i = 0; i < sdList.size(); i++) {  
302 - StorageDeposit sd = sdList.get(i);  
303 - if (changeSaleStatusOn(uid, sd.getDepositCode(), skupList.get(i))) {  
304 - LOGGER.info("changeSaleStatusOn success! uid {},depositeCode is {}, skup is {}", uid, sd.getDepositCode(), skupList.get(i));  
305 - sd.setNewSkup(skupList.get(i));  
306 - successList.add(sd);  
307 - } 308 + //TODO 入参定义不正确,没有寄存码和skup的映射关系
  309 + return null;
  310 + }
  311 +
  312 + private class DepositLock{
  313 + private int sellerUid;
  314 + private String depositCode;
  315 + private int unlockStatus = 0, lockStatus = 1;
  316 + DepositLock(int sellerUid, String depositCode){
  317 + this.sellerUid = sellerUid;
  318 + this.depositCode = depositCode;
  319 + }
  320 +
  321 + boolean lock(){
  322 + int rows = storageDepositMapper.updateStorageLockFlagByCAS(sellerUid, depositCode, lockStatus, unlockStatus);
  323 + LOGGER.info("in DepositLock.lock sellerUid {} depositCode {} rows {}", sellerUid, depositCode, rows);
  324 + return rows == 1;
  325 + }
  326 +
  327 + boolean unlock(){
  328 + int rows = storageDepositMapper.updateStorageLockFlagByCAS(sellerUid, depositCode, unlockStatus, lockStatus);
  329 + LOGGER.info("in DepositLock.unlock sellerUid {} depositCode {} rows {}", sellerUid, depositCode, rows);
  330 + return rows == 1;
308 } 331 }
309 - return successList;  
310 } 332 }
311 -  
312 /** 333 /**
313 * 批量上架-查询 334 * 批量上架-查询
314 - * TODO 应当锁定相关记录,加中间状态 335 + * 应当锁定相关记录,加中间状态
315 * @param uid 336 * @param uid
316 * @param storageId 337 * @param storageId
317 * @param num 338 * @param num
@@ -326,12 +347,19 @@ public class DepositServiceImpl implements DepositService { @@ -326,12 +347,19 @@ public class DepositServiceImpl implements DepositService {
326 } 347 }
327 List<StorageDeposit> lockedList = new ArrayList<>(sdList.size()); 348 List<StorageDeposit> lockedList = new ArrayList<>(sdList.size());
328 for (StorageDeposit sd : sdList) { 349 for (StorageDeposit sd : sdList) {
329 -  
330 - int rows = storageDepositMapper.updateStorageLockFlagByCAS(uid, sd.getDepositCode(), 1, 0);  
331 - if (rows == 1) {  
332 - lockedList.add(sd);  
333 - } else {  
334 - LOGGER.warn("getStorageDeposit4Publish updateStorageShelveStatusByCAS fail ,{}", sd); 350 + DepositLock lock = new DepositLock(uid, sd.getDepositCode());
  351 + try{
  352 + if (lock.lock()) {
  353 + lockedList.add(sd);
  354 + } else {
  355 + LOGGER.warn("getStorageDeposit4Publish updateStorageShelveStatusByCAS fail ,{}", sd);
  356 + }
  357 + }catch (Exception ex){
  358 + //release lock, give a second chance 2 survivor
  359 + lock.unlock();
  360 + LOGGER.warn("getStorageDeposit4Publish updateStorageShelveStatusByCAS occur exception {} - {}",
  361 + sd, Throwables.getStackTraceAsString(ex));
  362 + continue;
335 } 363 }
336 } 364 }
337 return lockedList; 365 return lockedList;
@@ -78,9 +78,6 @@ public class QuickDeliverPublishProcessor implements PublishProcessor<QuickDeliv @@ -78,9 +78,6 @@ public class QuickDeliverPublishProcessor implements PublishProcessor<QuickDeliv
78 } 78 }
79 79
80 80
81 -  
82 -  
83 -  
84 List<String> depositCodes = new ArrayList<>(depositPrdsize); 81 List<String> depositCodes = new ArrayList<>(depositPrdsize);
85 Map<String, AddressInfo> hiddenBackAddressMap = new HashMap<>(depositPrdsize), 82 Map<String, AddressInfo> hiddenBackAddressMap = new HashMap<>(depositPrdsize),
86 noHiddenBackAddressMap = new HashMap<>(depositPrdsize) 83 noHiddenBackAddressMap = new HashMap<>(depositPrdsize)