Authored by chenchao

use cas lock

package com.yohoufo.order.service.impl;
import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import com.yoho.core.dal.datasource.annotation.Database;
import com.yohobuy.ufo.model.order.bo.ButtonShowBo;
... ... @@ -32,6 +33,8 @@ import com.yohoufo.order.service.proxy.ProductProxyService;
import com.yohoufo.order.service.proxy.SellerNoticeFacade;
import com.yohoufo.order.service.seller.SkupService;
import com.yohoufo.order.utils.LoggerUtils;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -261,11 +264,18 @@ public class DepositServiceImpl implements DepositService {
LOGGER.info("changeSaleStatusOn uid {}, depositCode is {}, skup is {}", uid, depositCode, skup);
boolean result = storageDepositMapper.changeSaleStatusOn(uid, depositCode, skup) == 1;
if (result) {
StorageDeposit sd = storageDepositMapper.queryByDepositCode(uid, depositCode);
clearCache(uid, sd.getProductId(), sd.getStorageId());
cleanCacheWhenOnShelve(uid, depositCode);
//unlock
new DepositLock(uid, depositCode).unlock();
}
return result;
}
private void cleanCacheWhenOnShelve(Integer uid, String depositCode){
StorageDeposit sd = storageDepositMapper.queryByDepositCode(uid, depositCode);
clearCache(uid, sd.getProductId(), sd.getStorageId());
}
// 下架
@Override
@Database(ForceMaster=true)
... ... @@ -295,23 +305,34 @@ public class DepositServiceImpl implements DepositService {
// 批量上架
public List<StorageDeposit> changeSaleStatusOnBatch(Integer uid, Integer storageId, List<Integer> skupList) {
int count = skupList.size();
List<StorageDeposit> sdList = storageDepositMapper.getDepositOffs(uid, storageId, count);
List<StorageDeposit> successList = new ArrayList<>();
for (int i = 0; i < sdList.size(); i++) {
StorageDeposit sd = sdList.get(i);
if (changeSaleStatusOn(uid, sd.getDepositCode(), skupList.get(i))) {
LOGGER.info("changeSaleStatusOn success! uid {},depositeCode is {}, skup is {}", uid, sd.getDepositCode(), skupList.get(i));
sd.setNewSkup(skupList.get(i));
successList.add(sd);
}
//TODO 入参定义不正确,没有寄存码和skup的映射关系
return null;
}
private class DepositLock{
private int sellerUid;
private String depositCode;
private int unlockStatus = 0, lockStatus = 1;
DepositLock(int sellerUid, String depositCode){
this.sellerUid = sellerUid;
this.depositCode = depositCode;
}
boolean lock(){
int rows = storageDepositMapper.updateStorageLockFlagByCAS(sellerUid, depositCode, lockStatus, unlockStatus);
LOGGER.info("in DepositLock.lock sellerUid {} depositCode {} rows {}", sellerUid, depositCode, rows);
return rows == 1;
}
boolean unlock(){
int rows = storageDepositMapper.updateStorageLockFlagByCAS(sellerUid, depositCode, unlockStatus, lockStatus);
LOGGER.info("in DepositLock.unlock sellerUid {} depositCode {} rows {}", sellerUid, depositCode, rows);
return rows == 1;
}
return successList;
}
/**
* 批量上架-查询
* TODO 应当锁定相关记录,加中间状态
* 应当锁定相关记录,加中间状态
* @param uid
* @param storageId
* @param num
... ... @@ -326,12 +347,19 @@ public class DepositServiceImpl implements DepositService {
}
List<StorageDeposit> lockedList = new ArrayList<>(sdList.size());
for (StorageDeposit sd : sdList) {
int rows = storageDepositMapper.updateStorageLockFlagByCAS(uid, sd.getDepositCode(), 1, 0);
if (rows == 1) {
lockedList.add(sd);
} else {
LOGGER.warn("getStorageDeposit4Publish updateStorageShelveStatusByCAS fail ,{}", sd);
DepositLock lock = new DepositLock(uid, sd.getDepositCode());
try{
if (lock.lock()) {
lockedList.add(sd);
} else {
LOGGER.warn("getStorageDeposit4Publish updateStorageShelveStatusByCAS fail ,{}", sd);
}
}catch (Exception ex){
//release lock, give a second chance 2 survivor
lock.unlock();
LOGGER.warn("getStorageDeposit4Publish updateStorageShelveStatusByCAS occur exception {} - {}",
sd, Throwables.getStackTraceAsString(ex));
continue;
}
}
return lockedList;
... ...
... ... @@ -78,9 +78,6 @@ public class QuickDeliverPublishProcessor implements PublishProcessor<QuickDeliv
}
List<String> depositCodes = new ArrayList<>(depositPrdsize);
Map<String, AddressInfo> hiddenBackAddressMap = new HashMap<>(depositPrdsize),
noHiddenBackAddressMap = new HashMap<>(depositPrdsize)
... ...