RedisLockerHelper.cs 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. using Fuel.Infrastructure.Extension;
  2. using System;
  3. namespace Fuel.Infrastructure
  4. {
  5. /// <summary>
  6. /// Redis实现锁帮助类
  7. /// </summary>
  8. public class RedisLockerHelper
  9. {
  10. /// <summary>
  11. /// 获取redis分布式锁
  12. /// </summary>
  13. /// <param name="lockKeyName"></param>
  14. /// <param name="lockTimeout">自动过期时间(毫秒)</param>
  15. /// <returns></returns>
  16. public static bool GetRedisDistributedLock(string lockKeyName, long lockTimeout)
  17. {
  18. if (SetNx(lockKeyName, TimeExtension.GetNowTimeStamp(true) + lockTimeout, lockTimeout))
  19. {
  20. return true;
  21. }
  22. else
  23. {
  24. //未获取到锁,继续判断,判断时间戳看看是否可以重置并获取锁
  25. long lockValue = RedisHelper.Get<long>(lockKeyName);
  26. long time = TimeExtension.GetNowTimeStamp(true);
  27. if (time > lockValue)
  28. {
  29. //再次用当前时间戳getset
  30. //返回固定key的旧值,旧值判断是否可以获取锁
  31. long getsetResult = RedisHelper.GetSet<long>(lockKeyName, time);
  32. if (getsetResult == lockValue)
  33. {
  34. RedisHelper.Expire(lockKeyName, TimeSpan.FromMilliseconds(lockTimeout));
  35. return true;
  36. }
  37. else
  38. {
  39. return false;
  40. }
  41. }
  42. else
  43. {
  44. return false;
  45. }
  46. }
  47. }
  48. private static bool SetNx(string key, long time, double expireMS)
  49. {
  50. if (expireMS > 0)
  51. {
  52. if (RedisHelper.Set(key, time, TimeSpan.FromMilliseconds(expireMS), CSRedis.RedisExistence.Nx))
  53. return true;
  54. }
  55. else
  56. {
  57. if (RedisHelper.SetNx(key, time))
  58. {
  59. RedisHelper.Expire(key, TimeSpan.FromMilliseconds(expireMS));
  60. return true;
  61. }
  62. }
  63. return false;
  64. }
  65. }
  66. }