Redis 의 String 유형 및 Redis 를 사용 하여 주문 스 톱 판매 문 제 를 해결 합 니 다.

이 시 리 즈 는 Redis 분포 식 캐 시 를 공유 할 것 입 니 다.이 장 에 서 는 Redis 의 String 유형 과 Redis 를 어떻게 사용 하여 주문 의 초 판매 문 제 를 해결 하 는 지 간단하게 소개 합 니 다.
Redis 에서 5 가지 데이터 구조의 String 형식:key-value 의 캐 시,만 료 지원,value 는 512 M 을 초과 하지 않 습 니 다.

Redis 는 단일 스 레 드 입 니 다.예 를 들 어 SetAll&AppendToValue&Get Values&GetAndSetValue&Increment Value&Increment Value By 등 은 조합 명령 처럼 보이 지만 실제 적 으로 구체 적 인 명령 이 고 원자 적 인 명령 입 니 다.중간 상태 가 나타 날 수 없고 병발 상황 에 대응 할 수 있 습 니 다.다음은 코드 를 통 해 구체 적 인 사용 을 살 펴 보 겠 습 니 다.
먼저 데모 의 프로젝트 구 조 를 살 펴 보 겠 습 니 다.

이곳 에서 추천 하 는 것 은 ServiceStack 가방 입 니 다.비록 비용 이 들 고 1 시간 3600 번 의 요청 제한 이 있 지만 오픈 소스 입 니 다.소스 코드 를 다운로드 하여 풀 어서 사용 할 수 있 습 니 다.인터넷 에 관련 자료 가 많 을 것 입 니 다.관심 이 있 으 면 한 번 알 아 볼 수 있 습 니 다.
1.Redis 에서 String 형식 과 관련 된 API
먼저 Redis 클 라 이언 트 의 초기 화 작업 을 살 펴 보 겠 습 니 다.

using System;

namespace TianYa.Redis.Init
{
 /// <summary>
 /// redis      
 ///           
 /// </summary>
 public sealed class RedisConfigInfo
 {
  /// <summary>
  ///    Redis    
  /// format:ip1,ip2
  /// 
  ///   6379  
  /// </summary>
  public string WriteServerList = "127.0.0.1:6379";

  /// <summary>
  ///    Redis    
  /// format:ip1,ip2
  /// 
  ///   6379  
  /// </summary>
  public string ReadServerList = "127.0.0.1:6379";

  /// <summary>
  ///       
  /// </summary>
  public int MaxWritePoolSize = 60;

  /// <summary>
  ///       
  /// </summary>
  public int MaxReadPoolSize = 60;

  /// <summary>
  ///         ,  : 
  /// </summary>
  public int LocalCacheTime = 180;

  /// <summary>
  ///     
  /// </summary>
  public bool AutoStart = true;

  /// <summary>
  ///       ,        redis        ,
  ///  redis    ,     
  /// </summary>
  public bool RecordeLog = false;
 }
}

using ServiceStack.Redis;

namespace TianYa.Redis.Init
{
 /// <summary>
 /// Redis    
 /// </summary>
 public class RedisManager
 {
  /// <summary>
  /// Redis      
  /// </summary>
  private static RedisConfigInfo _redisConfigInfo = new RedisConfigInfo();

  /// <summary>
  /// Redis       
  /// </summary>
  private static PooledRedisClientManager _prcManager;

  /// <summary>
  ///       ,          
  /// </summary>
  static RedisManager()
  {
   CreateManager();
  }

  /// <summary>
  ///          
  /// </summary>
  private static void CreateManager()
  {
   string[] writeServerConStr = _redisConfigInfo.WriteServerList.Split(',');
   string[] readServerConStr = _redisConfigInfo.ReadServerList.Split(',');
   _prcManager = new PooledRedisClientManager(readServerConStr, writeServerConStr,
    new RedisClientManagerConfig
    {
     MaxWritePoolSize = _redisConfigInfo.MaxWritePoolSize,
     MaxReadPoolSize = _redisConfigInfo.MaxReadPoolSize,
     AutoStart = _redisConfigInfo.AutoStart,
    });
  }

  /// <summary>
  ///          
  /// </summary>
  public static IRedisClient GetClient()
  {
   return _prcManager.GetClient();
  }
 }
}

using System;
using TianYa.Redis.Init;
using ServiceStack.Redis;

namespace TianYa.Redis.Service
{
 /// <summary>
 /// redis     
 /// </summary>
 public abstract class RedisBase : IDisposable
 {
  /// <summary>
  /// Redis   
  /// </summary>
  protected IRedisClient _redisClient { get; private set; }

  /// <summary>
  ///     
  /// </summary>
  public RedisBase()
  {
   this._redisClient = RedisManager.GetClient();
  }

  private bool _disposed = false;
  protected virtual void Dispose(bool disposing)
  {
   if (!this._disposed)
   {
    if (disposing)
    {
     _redisClient.Dispose();
     _redisClient = null;
    }
   }

   this._disposed = true;
  }

  public void Dispose()
  {
   Dispose(true);
   GC.SuppressFinalize(this);
  }

  /// <summary>
  /// Redis      
  /// </summary>
  public void Transcation()
  {
   using (IRedisTransaction irt = this._redisClient.CreateTransaction())
   {
    try
    {
     irt.QueueCommand(r => r.Set("key", 20));
     irt.QueueCommand(r => r.Increment("key", 1));
     irt.Commit(); //    
    }
    catch (Exception ex)
    {
     irt.Rollback(); //    
     throw ex;
    }
   }
  }

  /// <summary>
  ///           
  /// </summary>
  public virtual void FlushAll()
  {
   _redisClient.FlushAll();
  }

  /// <summary>
  ///     DB     
  /// </summary>
  public void Save()
  {
   _redisClient.Save(); //   Save
  }

  /// <summary>
  ///       DB     
  /// </summary>
  public void SaveAsync()
  {
   _redisClient.SaveAsync(); //  Save
  }
 }
}
다음은 Redis 에서 String 형식 과 관련 된 API 를 직접 보 여 드 리 겠 습 니 다.

using System;
using System.Collections.Generic;

namespace TianYa.Redis.Service
{
 /// <summary>
 /// key-value     value          (   )
 /// </summary>
 public class RedisStringService : RedisBase
 {
  #region   

  /// <summary>
  ///       
  /// </summary>
  /// <param name="key">    </param>
  /// <param name="value">    </param>
  /// <returns></returns>
  public bool Set(string key, string value)
  {
   return base._redisClient.Set(key, value);
  }

  /// <summary>
  ///       
  /// </summary>
  /// <param name="key">    </param>
  /// <param name="value">    </param>
  /// <returns></returns>
  public bool Set<T>(string key, T value)
  {
   return base._redisClient.Set<T>(key, value);
  }

  /// <summary>
  ///          
  /// </summary>
  /// <param name="key">    </param>
  /// <param name="value">    </param>
  /// <param name="expireTime">    </param>
  /// <returns></returns>
  public bool Set(string key, string value, DateTime expireTime)
  {
   return base._redisClient.Set(key, value, expireTime);
  }

  /// <summary>
  ///          
  /// </summary>
  /// <param name="key">    </param>
  /// <param name="value">    </param>
  /// <param name="expireTime">    </param>
  /// <returns></returns>
  public bool Set<T>(string key, T value, DateTime expireTime)
  {
   return base._redisClient.Set<T>(key, value, expireTime);
  }

  /// <summary>
  ///          
  /// </summary>
  /// <param name="key">    </param>
  /// <param name="value">    </param>
  /// <param name="expireTime">    </param>
  /// <returns></returns>
  public bool Set<T>(string key, T value, TimeSpan expireTime)
  {
   return base._redisClient.Set<T>(key, value, expireTime);
  }

  /// <summary>
  ///     key/value
  /// </summary>
  public void SetAll(Dictionary<string, string> dic)
  {
   base._redisClient.SetAll(dic);
  }

  #endregion   

  #region   

  /// <summary>
  ///    key value     value,       
  /// </summary>
  public long AppendToValue(string key, string value)
  {
   return base._redisClient.AppendToValue(key, value);
  }

  #endregion   

  #region    

  /// <summary>
  ///     
  /// </summary>
  /// <param name="key">    </param>
  /// <returns></returns>
  public string Get(string key)
  {
   return base._redisClient.GetValue(key);
  }

  /// <summary>
  ///     
  /// </summary>
  /// <param name="key">    </param>
  /// <returns></returns>
  public T Get<T>(string key)
  {
   return
    _redisClient.ContainsKey(key)
    ? _redisClient.Get<T>(key)
    : default;
  }

  /// <summary>
  ///     key value 
  /// </summary>
  /// <param name="keys">      </param>
  /// <returns></returns>
  public List<string> Get(List<string> keys)
  {
   return base._redisClient.GetValues(keys);
  }

  /// <summary>
  ///     key value 
  /// </summary>
  /// <param name="keys">      </param>
  /// <returns></returns>
  public List<T> Get<T>(List<string> keys)
  {
   return base._redisClient.GetValues<T>(keys);
  }

  #endregion    

  #region         

  /// <summary>
  ///         
  /// </summary>
  /// <param name="key">    </param>
  /// <param name="value">    </param>
  /// <returns></returns>
  public string GetAndSetValue(string key, string value)
  {
   return base._redisClient.GetAndSetValue(key, value);
  }

  #endregion         

  #region     

  /// <summary>
  ///     
  /// </summary>
  /// <param name="key">    </param>
  /// <returns></returns>
  public bool Remove(string key)
  {
   return _redisClient.Remove(key);
  }

  /// <summary>
  ///       
  /// </summary>
  /// <param name="keys">      </param>
  public void RemoveAll(List<string> keys)
  {
   _redisClient.RemoveAll(keys);
  }

  #endregion     

  #region     

  /// <summary>
  ///       
  /// </summary>
  /// <param name="key">    </param>
  /// <returns></returns>
  public bool ContainsKey(string key)
  {
   return _redisClient.ContainsKey(key);
  }

  /// <summary>
  ///       
  /// </summary>
  /// <param name="key">    </param>
  /// <returns></returns>
  public long GetStringCount(string key)
  {
   return base._redisClient.GetStringCount(key);
  }

  /// <summary>
  ///   1,       
  /// </summary>
  /// <param name="key">    </param>
  /// <returns></returns>
  public long IncrementValue(string key)
  {
   return base._redisClient.IncrementValue(key);
  }

  /// <summary>
  ///   count,       
  /// </summary>
  /// <param name="key">    </param>
  /// <param name="count">   </param>
  /// <returns></returns>
  public long IncrementValueBy(string key, int count)
  {
   return base._redisClient.IncrementValueBy(key, count);
  }

  /// <summary>
  ///   1,       
  /// </summary>
  /// <param name="key">    </param>
  /// <returns></returns>
  public long DecrementValue(string key)
  {
   return base._redisClient.DecrementValue(key);
  }

  /// <summary>
  ///   count,       
  /// </summary>
  /// <param name="key">    </param>
  /// <param name="count">   </param>
  /// <returns></returns>
  public long DecrementValueBy(string key, int count)
  {
   return base._redisClient.DecrementValueBy(key, count);
  }

  #endregion     
 }
}
테스트 는 다음 과 같 습 니 다:

using System;

namespace MyRedis
{
 /// <summary>
 ///    
 /// </summary>
 public class Student
 {
  public int Id { get; set; }
  public string Name { get; set; }
  public string Remark { get; set; }
  public string Description { get; set; }
 }
}

using System;
using System.Collections.Generic;
using TianYa.Redis.Service;
using Newtonsoft.Json;

namespace MyRedis
{
 /// <summary>
 /// ServiceStack API            (1  3600     --   )
 /// </summary>
 public class ServiceStackTest
 {
  /// <summary>
  /// String
  /// key-value   ,    ,value   512M
  /// Redis     ,  SetAll & AppendToValue & GetValues & GetAndSetValue & IncrementValue & IncrementValueBy,
  ///           ,            ,         ,         ,          
  /// </summary>
  public static void ShowString()
  {
   var student1 = new Student()
   {
    Id = 10000,
    Name = "TianYa"
   };

   using (RedisStringService service = new RedisStringService())
   {
    service.Set("student1", student1);
    var stu = service.Get<Student>("student1");
    Console.WriteLine(JsonConvert.SerializeObject(stu));

    service.Set<int>("Age", 28);
    Console.WriteLine(service.IncrementValue("Age"));
    Console.WriteLine(service.IncrementValueBy("Age", 3));
    Console.WriteLine(service.DecrementValue("Age"));
    Console.WriteLine(service.DecrementValueBy("Age", 3));
   }
  }
 }
}

using System;

namespace MyRedis
{
 /// <summary>
 /// Redis:Remote Dictionary Server        
 ///       (      ),   5     (          ),          (      ),      --  --  --    。
 ///                ,        。        ,           。
 ///                 。
 ///                ,       ,     ,        。Redis         (     ),      ,        。(    )
 /// Redis       ,                 。
 /// Redis        ,      。                ,Redis       。
 /// Redis   5     :String、Hashtable、Set、ZSet List。
 /// </summary>
 class Program
 {
  static void Main(string[] args)
  {
   ServiceStackTest.ShowString();
   Console.ReadKey();
  }
 }
}
실행 결 과 는 다음 과 같 습 니 다.


Redis 의 String 유형 은 프로젝트 에서 가장 많이 사 용 됩 니 다.모두 가 알 고 있 을 것 입 니 다.여 기 는 더 이상 설명 을 하지 않 습 니 다.
2.Redis 를 사용 하여 주문 의 초 판매 문 제 를 해결 합 니 다.
우선 주문 의 초판 초과 판매 문제 가 무엇 인지 살 펴 보 겠 습 니 다.

/// <summary>
///           
///    :       
///                    ? 
///      ,           ,      ,       。
///   -1         ,      ,     。
///   10     ,       ?      。
/// </summary>
public class OverSellFailedTest
{
 private static bool _isGoOn = true; //        
 private static int _stock = 0; //    
 public static void Show()
 {
  _stock = 10;
  for (int i = 0; i < 5000; i++)
  {
   int k = i;
   Task.Run(() => //            
   {
    if (_isGoOn)
    {
     long index = _stock;
     Thread.Sleep(100); //          
     if (index >= 1)
     {
      _stock = _stock - 1; //    
      Console.WriteLine($"{k.ToString("0000")}    ,       {index}");
      //     ,      
     }
     else
     {
      if (_isGoOn)
      {
       _isGoOn = false;
      }

      Console.WriteLine($"{k.ToString("0000")}    ,       {index}");
     }
    }
    else
    {
     Console.WriteLine($"{k.ToString("0000")}    ......");
    }
   });
  }
 }
}
OverSellFailed Test.How()를 실행 한 결 과 는 다음 과 같 습 니 다.

운행 결 과 를 보면 한 상품 이 여러 사람 에 게 팔 렸 을 뿐만 아니 라 주문 수가 상품 수 를 초과 하 는 것 도 전형 적 인 초 살 과 매 문제 임 을 알 수 있다.
다음은 레 디 스 를 어떻게 사용 하여 주문 의 초 판매 문 제 를 해결 하 는 지 살 펴 보 겠 습 니 다.

/// <summary>
///   Redis          
///    :       
///  1、Redis     --           --           
///  2、   Redis,           ,          ,           ,      ,
///            redis,     ,           
///  3、Redis         ,       ,            
///  4、    /  ---  down ,        
///  5、      ---    ,    ,             (              )
/// </summary>
public class OverSellTest
{
 private static bool _isGoOn = true; //        
 public static void Show()
 {
  using (RedisStringService service = new RedisStringService())
  {
   service.Set<int>("Stock", 10); //  
  }

  for (int i = 0; i < 5000; i++)
  {
   int k = i;
   Task.Run(() => //            
   {
    using (RedisStringService service = new RedisStringService())
    {
     if (_isGoOn)
     {
      long index = service.DecrementValue("Stock"); // 1     
      if (index >= 0)
      {
       Console.WriteLine($"{k.ToString("0000")}    ,       {index}");
       //service.IncrementValue("Stock"); // 1,                
       //     ,      
      }
      else
      {
       if (_isGoOn)
       {
        _isGoOn = false;
       }

       Console.WriteLine($"{k.ToString("0000")}    ,       {index}");
      }
     }
     else
     {
      Console.WriteLine($"{k.ToString("0000")}    ......");
     }
    }
   });
  }
 }
}
OverSellTest.How()를 실행 한 결 과 는 다음 과 같 습 니 다.

운행 결 과 를 보면 레 디 스 를 사용 하면 주문 의 초판 초과 판매 문 제 를 잘 해결 할 수 있 음 을 알 수 있다.
이로써 본 고 는 모두 소개 되 었 습 니 다.당신 에 게 깨 우 침 이 있다 고 생각 되면 좋아요 를 눌 러 주세요!!
데모 소스 코드:
링크:https://pan.baidu.com/s/1vukiDxOLQYZX4Qd94izMpQ추출 코드:bdfm
이 글 은 블 로 거들 이 심혈 을 기울 여 작성 하여 옮 겨 실 었 습 니 다.이 원문 링크 를 유지 하 십시오.https://www.cnblogs.com/xyh9039/p/13979522.html
저작권 성명:만약 유사 가 있 으 면 순 전 히 우연 의 일치 입 니 다.권리 침해 가 있 으 면 즉시 본인 에 게 연락 하여 수정 하 십시오.감사합니다!!
레 디 스 의 String 유형 및 레 디 스 를 이용 한 주문 스 톱 오 버 문 제 를 해결 하 는 글 을 소개 합 니 다.더 많은 관련 레 디 스 가 주문 스 톱 오 버 문 제 를 해결 하 는 내용 은 예전 의 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 도 많은 지원 바 랍 니 다!

좋은 웹페이지 즐겨찾기