2020-09-30 多线程添加redis锁控制并发

这段代码展示了如何使用 RedisLock 实现并发控制。在不同场景下,如 rollback 操作、转换导入列表和创建批量请求时,通过加锁确保操作的原子性和一致性。当加锁失败或操作条件不满足时,会进行相应的错误处理,如移除列表中的元素或记录日志。此外,还提供了 RedisLockClient 工具类用于获取和释放锁。
摘要由CSDN通过智能技术生成
使用redis锁:直接上代码,参考验证
RedisLock lock = null;
try {
   lock =RedisLockClient.getLock(String.format("claimID_%s",claimId));
   if (lock!=null) {
      return bpmProcessService.rollBack(workitemId, handlerName);
   }else {
      throw new BPMClientException(BPMClientException.MSG_ID.SUBMIT_ACTION_PERFORMING, claimId);
   }
} finally {
   if (lock!=null) {
      lock.unlock();
   }
}

 

 

public void convertToImportList(List<ClaimInfoBean> list) {
   List<RedisLock> lockList = new ArrayList<RedisLock>();
   if (list != null && !list.isEmpty()) {
      try {
         for (int i = list.size() - 1; i > -1; i--) {
            ClaimInfoBean claimInfoBean = list.get(i);
            ClaimBase claimBase = claimInfoBean.getClaimBase();
            String key = String.valueOf(claimBase.getClaimNo());
            RedisLock lock = null;
            try {
               lock = RedisLockClient.getLock(key);
            } catch (Exception e) {
               logger.error(String.format("claimNo[%s] 加锁失败移除该批次", claimBase.getClaimNo()),e);
               //获取redis锁异常后,去除该单据
               list.remove(i);
               continue;
            }
            if (lock != null) {
               lockList.add(lock);
               if (!claimBaseService.changeInvoiceStatusToImporting(claimBase.getClaimId())) {
                  logger.info(String.format("ClaimId[%s]ClaimNo[%s]当前状态为导入中[%s],请刷新状态", claimBase.getClaimId(), claimBase.getClaimNo(), ClaimExt.InvoiceState.DRZ.code));
                  list.remove(i);
               }
            } else {
               // other status , skip the record.
               logger.error(String.format("ClaimId[%s]ClaimNo[%s]并发控制,请稍候执行", claimBase.getClaimId(), claimBase.getClaimNo()));
               list.remove(i);
            }
         }
         ClaimTaskEsbBean esbBean = claimTaskEsbDAO.getClaimTaskEsbBeanByTaskCode(ClaimTaskConstant.CLAIM_TASK_51);
         super.checkAndImport(list,esbBean,esbBean.getEsbUrl());
      } finally {
         RedisLockClient.unLock(lockList);
      }
   }
   
}

 

 

 

 

 

List<PayRequestLine> requestList = payRequestLineService.getPayRequestLineByOuCode(queryParams);
List<RedisLock> locks = null;
// 获取创建最大数量
if (requestList == null || requestList.isEmpty()) {
   return;
}
try {
   locks = RedisLockClient.getLock(requestList);
   if (locks != null) {
      List<List<PayRequestLine>> pageList = getPageRequestLineList(requestList, operator.getPaymentMax() == null ? 10 : operator.getPaymentMax());
      if (pageList != null) {
         for (List<PayRequestLine> lineList : pageList) {
            this.createBatchByPayReqLines(operator, lineList, createMode);
         }
      }
   }

} finally {
   RedisLockClient.unLock(locks);
}

 

 

 

 

 

 

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import com.crc.fssc.efinance.bpm.service.process.Impl.BPMClient;
import com.crc.fssc.efinance.claim.common.pojo.ClaimBase;
import com.crc.fssc.efinance.claim.payment.pojo.PayLineDetail;
import com.crc.fssc.efinance.claim.payment.pojo.PayRequestLine;
import com.google.common.collect.Lists;

/**
RedisLockClient工具类
 * @Auther: 
 * @Date: 
 * @Company: 
 * @Description:
 */
public class RedisLockClient {

   private static final Log myLogger = LogFactory.getLog(BPMClient.class);

   
   public static RedisLock getLock(final String key, long expireSeconds) {

      // 每次重新生成一个RedisLockUtils
      WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();
      RedisLockUtils u = (RedisLockUtils) wac.getBean("redisLockUtils");

      return u.getLock(key, expireSeconds);
   }

   public static RedisLock getLock(final String key) {
      return getLock(key, 600);
   }

   public static List<RedisLock> getLock(final List<?> objects, String filedName) {
      
      boolean isAllLock = true;
      List<RedisLock> locks = new ArrayList<RedisLock>();
      Set<String> lockSet = new HashSet<String>();
      if (objects != null) {

         for (Object dataObject : objects) {

            if (dataObject != null) {

               Field field = ReflectionUtils.findField(dataObject.getClass(), filedName);
               String key;
               if (field == null) {
                  isAllLock = false;
                  break;
               } else {

                  field.setAccessible(true);
                  Object filedObject = ReflectionUtils.getField(field, dataObject);
                  if (filedObject != null) {
                     key = String.format("%s_%s", filedName, filedObject.toString());

                     if (lockSet.contains(key)) {
                        continue;
                     } else {
                        RedisLock lock = getLock(key, 900);
                        if (lock != null) {
                           locks.add(lock);
                           lockSet.add(key);
                        } else {
                           isAllLock = false;
                           break;
                        }

                     }
                  }
               }
            }
            
         }
      } else {
         isAllLock = false;
      }
      
      if (!isAllLock) {
         for (RedisLock l : locks) {
            l.unlock();
         }
         locks = null;
      }
      return locks;
   }
   
   @SuppressWarnings("unchecked")
   public static List<RedisLock> getLock(final List<?> objects) {
      
      String filedName="";
      Object o = objects.get(0);
      
      if( o instanceof String) {
         return getLockByString((List<String>) objects);
      }else if( o instanceof PayRequestLine) {
         filedName  ="invoiceNo";
      }else if( o instanceof PayLineDetail) {
         filedName  ="payLineDetailId";
      }else if( o instanceof ClaimBase) {
         filedName  ="claimNo";
      }else {
         myLogger.error(String.format(String.format("Not defefine Object:[%s]", o.getClass().getName())));
         return null;
      }
      
      
      return getLock(objects, filedName);
   
   }

   public static List<RedisLock> getLockByString(final List<String> keys) {

      boolean isAllLock = true;
      List<RedisLock> locks = new ArrayList<RedisLock>();
      if (keys != null) {

         for (String key : keys) {
            RedisLock lock = getLock(key, 900);

            if (lock != null) {
               locks.add(lock);
            } else {
               isAllLock = false;
               break;
            }
         }
      }

      if (!isAllLock) {
         for (RedisLock l : locks) {
            l.unlock();
         }
         locks = null;
      }
      return locks;
   }

   public static void unLock(RedisLock lock) {
      if (lock != null) {
         lock.unlock();
      }
   }

   public static void unLock(List<RedisLock> lockList) {
      if (lockList != null) {
         for (RedisLock lock : lockList) {
            unLock(lock);
         }
      }
   }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程治铭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值